// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Code generated by sidekick. DO NOT EDIT.

#![allow(rustdoc::redundant_explicit_links)]
#![allow(rustdoc::broken_intra_doc_links)]
#![no_implicit_prelude]
extern crate async_trait;
extern crate bytes;
extern crate gax;
extern crate gaxi;
extern crate gtype;
extern crate lazy_static;
extern crate longrunning;
extern crate lro;
extern crate reqwest;
extern crate serde;
extern crate serde_json;
extern crate serde_with;
extern crate std;
extern crate tracing;
extern crate wkt;

mod debug;
mod deserialize;
mod serialize;

/// The desired input location information.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct InputConfig {
    /// The input data format that used to store the model in Cloud Storage.
    pub data_format: crate::model::DataFormat,

    /// The location of the input model in cloud storage.
    /// Required.
    pub source: std::option::Option<crate::model::input_config::Source>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl InputConfig {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [data_format][crate::model::InputConfig::data_format].
    pub fn set_data_format<T: std::convert::Into<crate::model::DataFormat>>(
        mut self,
        v: T,
    ) -> Self {
        self.data_format = v.into();
        self
    }

    /// Sets the value of [source][crate::model::InputConfig::source].
    ///
    /// Note that all the setters affecting `source` are mutually
    /// exclusive.
    pub fn set_source<
        T: std::convert::Into<std::option::Option<crate::model::input_config::Source>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.source = v.into();
        self
    }

    /// The value of [source][crate::model::InputConfig::source]
    /// if it holds a `GcsSource`, `None` if the field is not set or
    /// holds a different branch.
    pub fn gcs_source(&self) -> std::option::Option<&std::boxed::Box<crate::model::GcsSource>> {
        #[allow(unreachable_patterns)]
        self.source.as_ref().and_then(|v| match v {
            crate::model::input_config::Source::GcsSource(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [source][crate::model::InputConfig::source]
    /// to hold a `GcsSource`.
    ///
    /// Note that all the setters affecting `source` are
    /// mutually exclusive.
    pub fn set_gcs_source<T: std::convert::Into<std::boxed::Box<crate::model::GcsSource>>>(
        mut self,
        v: T,
    ) -> Self {
        self.source =
            std::option::Option::Some(crate::model::input_config::Source::GcsSource(v.into()));
        self
    }
}

impl wkt::message::Message for InputConfig {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.InputConfig"
    }
}

/// Defines additional types related to [InputConfig].
pub mod input_config {
    #[allow(unused_imports)]
    use super::*;

    /// The location of the input model in cloud storage.
    /// Required.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Source {
        /// The Google Cloud Storage location to read the input from. This must be a
        /// single file.
        GcsSource(std::boxed::Box<crate::model::GcsSource>),
    }
}

/// The desired output location.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct OutputConfig {
    /// The output data format that used to store the results in Cloud Storage.
    pub data_format: crate::model::DataFormat,

    /// The location of the output result in cloud storage.
    /// Required.
    pub destination: std::option::Option<crate::model::output_config::Destination>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl OutputConfig {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [data_format][crate::model::OutputConfig::data_format].
    pub fn set_data_format<T: std::convert::Into<crate::model::DataFormat>>(
        mut self,
        v: T,
    ) -> Self {
        self.data_format = v.into();
        self
    }

    /// Sets the value of [destination][crate::model::OutputConfig::destination].
    ///
    /// Note that all the setters affecting `destination` are mutually
    /// exclusive.
    pub fn set_destination<
        T: std::convert::Into<std::option::Option<crate::model::output_config::Destination>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.destination = v.into();
        self
    }

    /// The value of [destination][crate::model::OutputConfig::destination]
    /// if it holds a `GcsDestination`, `None` if the field is not set or
    /// holds a different branch.
    pub fn gcs_destination(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::GcsDestination>> {
        #[allow(unreachable_patterns)]
        self.destination.as_ref().and_then(|v| match v {
            crate::model::output_config::Destination::GcsDestination(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [destination][crate::model::OutputConfig::destination]
    /// to hold a `GcsDestination`.
    ///
    /// Note that all the setters affecting `destination` are
    /// mutually exclusive.
    pub fn set_gcs_destination<
        T: std::convert::Into<std::boxed::Box<crate::model::GcsDestination>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.destination = std::option::Option::Some(
            crate::model::output_config::Destination::GcsDestination(v.into()),
        );
        self
    }
}

impl wkt::message::Message for OutputConfig {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.OutputConfig"
    }
}

/// Defines additional types related to [OutputConfig].
pub mod output_config {
    #[allow(unused_imports)]
    use super::*;

    /// The location of the output result in cloud storage.
    /// Required.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Destination {
        /// The Google Cloud Storage location to write the output to.
        GcsDestination(std::boxed::Box<crate::model::GcsDestination>),
    }
}

/// The Google Cloud Storage location where the input file will be read from.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GcsSource {
    /// Required. URI of the Google Cloud Storage location.
    pub uri: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GcsSource {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [uri][crate::model::GcsSource::uri].
    pub fn set_uri<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.uri = v.into();
        self
    }
}

impl wkt::message::Message for GcsSource {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.GcsSource"
    }
}

/// The Google Cloud Storage location where the output file will be written to.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GcsDestination {
    /// Required. URI of the Google Cloud Storage location.
    pub uri: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GcsDestination {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [uri][crate::model::GcsDestination::uri].
    pub fn set_uri<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.uri = v.into();
        self
    }
}

impl wkt::message::Message for GcsDestination {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.GcsDestination"
    }
}

/// The long running operation metadata for async model related methods.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AsyncModelMetadata {
    /// The state of the current operation.
    pub state: crate::model::async_model_metadata::State,

    /// A message providing more details about the current state of the operation.
    /// For example, the error message if the operation is failed.
    pub state_message: std::string::String,

    /// The creation time of the operation.
    pub create_time: std::option::Option<wkt::Timestamp>,

    /// The last update time of the operation.
    pub update_time: std::option::Option<wkt::Timestamp>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AsyncModelMetadata {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [state][crate::model::AsyncModelMetadata::state].
    pub fn set_state<T: std::convert::Into<crate::model::async_model_metadata::State>>(
        mut self,
        v: T,
    ) -> Self {
        self.state = v.into();
        self
    }

    /// Sets the value of [state_message][crate::model::AsyncModelMetadata::state_message].
    pub fn set_state_message<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.state_message = v.into();
        self
    }

    /// Sets the value of [create_time][crate::model::AsyncModelMetadata::create_time].
    pub fn set_create_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.create_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [create_time][crate::model::AsyncModelMetadata::create_time].
    pub fn set_or_clear_create_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.create_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_time][crate::model::AsyncModelMetadata::update_time].
    pub fn set_update_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.update_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_time][crate::model::AsyncModelMetadata::update_time].
    pub fn set_or_clear_update_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.update_time = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for AsyncModelMetadata {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.AsyncModelMetadata"
    }
}

/// Defines additional types related to [AsyncModelMetadata].
pub mod async_model_metadata {
    #[allow(unused_imports)]
    use super::*;

    /// Possible states of the operation.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum State {
        /// The default value. This value is used if the state is omitted.
        Unspecified,
        /// Request is being processed.
        Running,
        /// The operation completed successfully.
        Succeeded,
        /// The operation was cancelled.
        Cancelled,
        /// The operation has failed.
        Failed,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [State::value] or
        /// [State::name].
        UnknownValue(state::UnknownValue),
    }

    #[doc(hidden)]
    pub mod state {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl State {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::Running => std::option::Option::Some(1),
                Self::Succeeded => std::option::Option::Some(2),
                Self::Cancelled => std::option::Option::Some(3),
                Self::Failed => std::option::Option::Some(4),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("STATE_UNSPECIFIED"),
                Self::Running => std::option::Option::Some("RUNNING"),
                Self::Succeeded => std::option::Option::Some("SUCCEEDED"),
                Self::Cancelled => std::option::Option::Some("CANCELLED"),
                Self::Failed => std::option::Option::Some("FAILED"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for State {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for State {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for State {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::Running,
                2 => Self::Succeeded,
                3 => Self::Cancelled,
                4 => Self::Failed,
                _ => Self::UnknownValue(state::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for State {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "STATE_UNSPECIFIED" => Self::Unspecified,
                "RUNNING" => Self::Running,
                "SUCCEEDED" => Self::Succeeded,
                "CANCELLED" => Self::Cancelled,
                "FAILED" => Self::Failed,
                _ => Self::UnknownValue(state::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for State {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::Running => serializer.serialize_i32(1),
                Self::Succeeded => serializer.serialize_i32(2),
                Self::Cancelled => serializer.serialize_i32(3),
                Self::Failed => serializer.serialize_i32(4),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for State {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<State>::new(
                ".google.cloud.optimization.v1.AsyncModelMetadata.State",
            ))
        }
    }
}

/// Request to be given to a tour optimization solver which defines the
/// shipment model to solve as well as optimization parameters.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct OptimizeToursRequest {
    /// Required. Target project and location to make a call.
    ///
    /// Format: `projects/{project-id}/locations/{location-id}`.
    ///
    /// If no location is specified, a region will be chosen automatically.
    pub parent: std::string::String,

    /// If this timeout is set, the server returns a response before the timeout
    /// period has elapsed or the server deadline for synchronous requests is
    /// reached, whichever is sooner.
    ///
    /// For asynchronous requests, the server will generate a solution (if
    /// possible) before the timeout has elapsed.
    pub timeout: std::option::Option<wkt::Duration>,

    /// Shipment model to solve.
    pub model: std::option::Option<crate::model::ShipmentModel>,

    /// By default, the solving mode is `DEFAULT_SOLVE` (0).
    pub solving_mode: crate::model::optimize_tours_request::SolvingMode,

    /// Search mode used to solve the request.
    pub search_mode: crate::model::optimize_tours_request::SearchMode,

    /// Guide the optimization algorithm in finding a first solution that is
    /// similar to a previous solution.
    ///
    /// The model is constrained when the first solution is built.
    /// Any shipments not performed on a route are implicitly skipped in the first
    /// solution, but they may be performed in successive solutions.
    ///
    /// The solution must satisfy some basic validity assumptions:
    ///
    /// * for all routes, `vehicle_index` must be in range and not be duplicated.
    /// * for all visits, `shipment_index` and `visit_request_index` must be
    ///   in range.
    /// * a shipment may only be referenced on one route.
    /// * the pickup of a pickup-delivery shipment must be performed before
    ///   the delivery.
    /// * no more than one pickup alternative or delivery alternative of
    ///   a shipment may be performed.
    /// * for all routes, times are increasing (i.e., `vehicle_start_time
    ///   <= visits[0].start_time <= visits[1].start_time ...
    ///   <= vehicle_end_time`).
    /// * a shipment may only be performed on a vehicle that is allowed. A
    ///   vehicle is allowed if
    ///   [Shipment.allowed_vehicle_indices][google.cloud.optimization.v1.Shipment.allowed_vehicle_indices]
    ///   is empty or its `vehicle_index` is included in
    ///   [Shipment.allowed_vehicle_indices][google.cloud.optimization.v1.Shipment.allowed_vehicle_indices].
    ///
    /// If the injected solution is not feasible, a validation error is not
    /// necessarily returned and an error indicating infeasibility may be returned
    /// instead.
    ///
    /// [google.cloud.optimization.v1.Shipment.allowed_vehicle_indices]: crate::model::Shipment::allowed_vehicle_indices
    pub injected_first_solution_routes: std::vec::Vec<crate::model::ShipmentRoute>,

    /// Constrain the optimization algorithm to find a final solution that is
    /// similar to a previous solution. For example, this may be used to freeze
    /// portions of routes which have already been completed or which are to be
    /// completed but must not be modified.
    ///
    /// If the injected solution is not feasible, a validation error is not
    /// necessarily returned and an error indicating infeasibility may be returned
    /// instead.
    pub injected_solution_constraint: std::option::Option<crate::model::InjectedSolutionConstraint>,

    /// If non-empty, the given routes will be refreshed, without modifying their
    /// underlying sequence of visits or travel times: only other details will be
    /// updated. This does not solve the model.
    ///
    /// As of 2020/11, this only populates the polylines of non-empty routes and
    /// requires that `populate_polylines` is true.
    ///
    /// The `route_polyline` fields of the passed-in routes may be inconsistent
    /// with route `transitions`.
    ///
    /// This field must not be used together with `injected_first_solution_routes`
    /// or `injected_solution_constraint`.
    ///
    /// `Shipment.ignore` and `Vehicle.ignore` have no effect on the behavior.
    /// Polylines are still populated between all visits in all non-empty routes
    /// regardless of whether the related shipments or vehicles are ignored.
    pub refresh_details_routes: std::vec::Vec<crate::model::ShipmentRoute>,

    /// If true:
    ///
    /// * uses
    ///   [ShipmentRoute.vehicle_label][google.cloud.optimization.v1.ShipmentRoute.vehicle_label]
    ///   instead of `vehicle_index` to
    ///   match routes in an injected solution with vehicles in the request;
    ///   reuses the mapping of original
    ///   [ShipmentRoute.vehicle_index][google.cloud.optimization.v1.ShipmentRoute.vehicle_index]
    ///   to new
    ///   [ShipmentRoute.vehicle_index][google.cloud.optimization.v1.ShipmentRoute.vehicle_index]
    ///   to update
    ///   [ConstraintRelaxation.vehicle_indices][google.cloud.optimization.v1.InjectedSolutionConstraint.ConstraintRelaxation.vehicle_indices]
    ///   if non-empty, but the mapping must be unambiguous (i.e., multiple
    ///   `ShipmentRoute`s must not share the same original `vehicle_index`).
    /// * uses
    ///   [ShipmentRoute.Visit.shipment_label][google.cloud.optimization.v1.ShipmentRoute.Visit.shipment_label]
    ///   instead of `shipment_index`
    ///   to match visits in an injected solution with shipments in the request;
    /// * uses
    ///   [SkippedShipment.label][google.cloud.optimization.v1.SkippedShipment.label]
    ///   instead of
    ///   [SkippedShipment.index][google.cloud.optimization.v1.SkippedShipment.index]
    ///   to
    ///   match skipped shipments in the injected solution with request
    ///   shipments.
    ///
    /// This interpretation applies to the `injected_first_solution_routes`,
    /// `injected_solution_constraint`, and `refresh_details_routes` fields.
    /// It can be used when shipment or vehicle indices in the request have
    /// changed since the solution was created, perhaps because shipments or
    /// vehicles have been removed from or added to the request.
    ///
    /// If true, labels in the following categories must appear at most once in
    /// their category:
    ///
    /// * [Vehicle.label][google.cloud.optimization.v1.Vehicle.label] in the
    ///   request;
    /// * [Shipment.label][google.cloud.optimization.v1.Shipment.label] in the
    ///   request;
    /// * [ShipmentRoute.vehicle_label][google.cloud.optimization.v1.ShipmentRoute.vehicle_label] in the injected solution;
    /// * [SkippedShipment.label][google.cloud.optimization.v1.SkippedShipment.label] and [ShipmentRoute.Visit.shipment_label][google.cloud.optimization.v1.ShipmentRoute.Visit.shipment_label] in
    ///   the injected solution (except pickup/delivery visit pairs, whose
    ///   `shipment_label` must appear twice).
    ///
    /// If a `vehicle_label` in the injected solution does not correspond to a
    /// request vehicle, the corresponding route is removed from the solution
    /// along with its visits. If a `shipment_label` in the injected solution does
    /// not correspond to a request shipment, the corresponding visit is removed
    /// from the solution. If a
    /// [SkippedShipment.label][google.cloud.optimization.v1.SkippedShipment.label]
    /// in the injected solution does not correspond to a request shipment, the
    /// `SkippedShipment` is removed from the solution.
    ///
    /// Removing route visits or entire routes from an injected solution may
    /// have an effect on the implied constraints, which may lead to change in
    /// solution, validation errors, or infeasibility.
    ///
    /// NOTE: The caller must ensure that each
    /// [Vehicle.label][google.cloud.optimization.v1.Vehicle.label] (resp.
    /// [Shipment.label][google.cloud.optimization.v1.Shipment.label]) uniquely
    /// identifies a vehicle (resp. shipment) entity used across the two relevant
    /// requests: the past request that produced the `OptimizeToursResponse` used
    /// in the injected solution and the current request that includes the injected
    /// solution. The uniqueness checks described above are not enough to guarantee
    /// this requirement.
    ///
    /// [google.cloud.optimization.v1.InjectedSolutionConstraint.ConstraintRelaxation.vehicle_indices]: crate::model::injected_solution_constraint::ConstraintRelaxation::vehicle_indices
    /// [google.cloud.optimization.v1.Shipment.label]: crate::model::Shipment::label
    /// [google.cloud.optimization.v1.ShipmentRoute.Visit.shipment_label]: crate::model::shipment_route::Visit::shipment_label
    /// [google.cloud.optimization.v1.ShipmentRoute.vehicle_index]: crate::model::ShipmentRoute::vehicle_index
    /// [google.cloud.optimization.v1.ShipmentRoute.vehicle_label]: crate::model::ShipmentRoute::vehicle_label
    /// [google.cloud.optimization.v1.SkippedShipment.index]: crate::model::SkippedShipment::index
    /// [google.cloud.optimization.v1.SkippedShipment.label]: crate::model::SkippedShipment::label
    /// [google.cloud.optimization.v1.Vehicle.label]: crate::model::Vehicle::label
    pub interpret_injected_solutions_using_labels: bool,

    /// Consider traffic estimation in calculating `ShipmentRoute` fields
    /// [Transition.travel_duration][google.cloud.optimization.v1.ShipmentRoute.Transition.travel_duration],
    /// [Visit.start_time][google.cloud.optimization.v1.ShipmentRoute.Visit.start_time],
    /// and `vehicle_end_time`; in setting the
    /// [ShipmentRoute.has_traffic_infeasibilities][google.cloud.optimization.v1.ShipmentRoute.has_traffic_infeasibilities]
    /// field, and in calculating the
    /// [OptimizeToursResponse.total_cost][google.cloud.optimization.v1.OptimizeToursResponse.total_cost]
    /// field.
    ///
    /// [google.cloud.optimization.v1.OptimizeToursResponse.total_cost]: crate::model::OptimizeToursResponse::total_cost
    /// [google.cloud.optimization.v1.ShipmentRoute.Transition.travel_duration]: crate::model::shipment_route::Transition::travel_duration
    /// [google.cloud.optimization.v1.ShipmentRoute.Visit.start_time]: crate::model::shipment_route::Visit::start_time
    /// [google.cloud.optimization.v1.ShipmentRoute.has_traffic_infeasibilities]: crate::model::ShipmentRoute::has_traffic_infeasibilities
    pub consider_road_traffic: bool,

    /// If true, polylines will be populated in response `ShipmentRoute`s.
    pub populate_polylines: bool,

    /// If true, polylines will be populated in response
    /// [ShipmentRoute.transitions][google.cloud.optimization.v1.ShipmentRoute.transitions].
    /// Note that in this case, the polylines will also be populated in the
    /// deprecated `travel_steps`.
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute.transitions]: crate::model::ShipmentRoute::transitions
    pub populate_transition_polylines: bool,

    /// If this is set, then the request can have a deadline
    /// (see <https://grpc.io/blog/deadlines>) of up to 60 minutes.
    /// Otherwise, the maximum deadline is only 30 minutes.
    /// Note that long-lived requests have a significantly larger (but still small)
    /// risk of interruption.
    pub allow_large_deadline_despite_interruption_risk: bool,

    /// If true, travel distances will be computed using geodesic distances instead
    /// of Google Maps distances, and travel times will be computed using geodesic
    /// distances with a speed defined by `geodesic_meters_per_second`.
    pub use_geodesic_distances: bool,

    /// When `use_geodesic_distances` is true, this field must be set and defines
    /// the speed applied to compute travel times. Its value must be at least 1.0
    /// meters/seconds.
    pub geodesic_meters_per_second: std::option::Option<f64>,

    /// Truncates the number of validation errors returned. These errors are
    /// typically attached to an INVALID_ARGUMENT error payload as a BadRequest
    /// error detail (<https://cloud.google.com/apis/design/errors#error_details>),
    /// unless solving_mode=VALIDATE_ONLY: see the
    /// [OptimizeToursResponse.validation_errors][google.cloud.optimization.v1.OptimizeToursResponse.validation_errors]
    /// field.
    /// This defaults to 100 and is capped at 10,000.
    ///
    /// [google.cloud.optimization.v1.OptimizeToursResponse.validation_errors]: crate::model::OptimizeToursResponse::validation_errors
    pub max_validation_errors: std::option::Option<i32>,

    /// Label that may be used to identify this request, reported back in the
    /// [OptimizeToursResponse.request_label][google.cloud.optimization.v1.OptimizeToursResponse.request_label].
    ///
    /// [google.cloud.optimization.v1.OptimizeToursResponse.request_label]: crate::model::OptimizeToursResponse::request_label
    pub label: std::string::String,

    /// Deprecated: Use
    /// [OptimizeToursRequest.populate_transition_polylines][google.cloud.optimization.v1.OptimizeToursRequest.populate_transition_polylines]
    /// instead. If true, polylines will be populated in response
    /// [ShipmentRoute.transitions][google.cloud.optimization.v1.ShipmentRoute.transitions].
    /// Note that in this case, the polylines will also be populated in the
    /// deprecated `travel_steps`.
    ///
    /// [google.cloud.optimization.v1.OptimizeToursRequest.populate_transition_polylines]: crate::model::OptimizeToursRequest::populate_transition_polylines
    /// [google.cloud.optimization.v1.ShipmentRoute.transitions]: crate::model::ShipmentRoute::transitions
    #[deprecated]
    pub populate_travel_step_polylines: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl OptimizeToursRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::OptimizeToursRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [timeout][crate::model::OptimizeToursRequest::timeout].
    pub fn set_timeout<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.timeout = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [timeout][crate::model::OptimizeToursRequest::timeout].
    pub fn set_or_clear_timeout<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.timeout = v.map(|x| x.into());
        self
    }

    /// Sets the value of [model][crate::model::OptimizeToursRequest::model].
    pub fn set_model<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ShipmentModel>,
    {
        self.model = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [model][crate::model::OptimizeToursRequest::model].
    pub fn set_or_clear_model<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ShipmentModel>,
    {
        self.model = v.map(|x| x.into());
        self
    }

    /// Sets the value of [solving_mode][crate::model::OptimizeToursRequest::solving_mode].
    pub fn set_solving_mode<
        T: std::convert::Into<crate::model::optimize_tours_request::SolvingMode>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.solving_mode = v.into();
        self
    }

    /// Sets the value of [search_mode][crate::model::OptimizeToursRequest::search_mode].
    pub fn set_search_mode<
        T: std::convert::Into<crate::model::optimize_tours_request::SearchMode>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.search_mode = v.into();
        self
    }

    /// Sets the value of [injected_first_solution_routes][crate::model::OptimizeToursRequest::injected_first_solution_routes].
    pub fn set_injected_first_solution_routes<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::ShipmentRoute>,
    {
        use std::iter::Iterator;
        self.injected_first_solution_routes = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [injected_solution_constraint][crate::model::OptimizeToursRequest::injected_solution_constraint].
    pub fn set_injected_solution_constraint<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::InjectedSolutionConstraint>,
    {
        self.injected_solution_constraint = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [injected_solution_constraint][crate::model::OptimizeToursRequest::injected_solution_constraint].
    pub fn set_or_clear_injected_solution_constraint<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::InjectedSolutionConstraint>,
    {
        self.injected_solution_constraint = v.map(|x| x.into());
        self
    }

    /// Sets the value of [refresh_details_routes][crate::model::OptimizeToursRequest::refresh_details_routes].
    pub fn set_refresh_details_routes<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::ShipmentRoute>,
    {
        use std::iter::Iterator;
        self.refresh_details_routes = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [interpret_injected_solutions_using_labels][crate::model::OptimizeToursRequest::interpret_injected_solutions_using_labels].
    pub fn set_interpret_injected_solutions_using_labels<T: std::convert::Into<bool>>(
        mut self,
        v: T,
    ) -> Self {
        self.interpret_injected_solutions_using_labels = v.into();
        self
    }

    /// Sets the value of [consider_road_traffic][crate::model::OptimizeToursRequest::consider_road_traffic].
    pub fn set_consider_road_traffic<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.consider_road_traffic = v.into();
        self
    }

    /// Sets the value of [populate_polylines][crate::model::OptimizeToursRequest::populate_polylines].
    pub fn set_populate_polylines<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.populate_polylines = v.into();
        self
    }

    /// Sets the value of [populate_transition_polylines][crate::model::OptimizeToursRequest::populate_transition_polylines].
    pub fn set_populate_transition_polylines<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.populate_transition_polylines = v.into();
        self
    }

    /// Sets the value of [allow_large_deadline_despite_interruption_risk][crate::model::OptimizeToursRequest::allow_large_deadline_despite_interruption_risk].
    pub fn set_allow_large_deadline_despite_interruption_risk<T: std::convert::Into<bool>>(
        mut self,
        v: T,
    ) -> Self {
        self.allow_large_deadline_despite_interruption_risk = v.into();
        self
    }

    /// Sets the value of [use_geodesic_distances][crate::model::OptimizeToursRequest::use_geodesic_distances].
    pub fn set_use_geodesic_distances<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.use_geodesic_distances = v.into();
        self
    }

    /// Sets the value of [geodesic_meters_per_second][crate::model::OptimizeToursRequest::geodesic_meters_per_second].
    pub fn set_geodesic_meters_per_second<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.geodesic_meters_per_second = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [geodesic_meters_per_second][crate::model::OptimizeToursRequest::geodesic_meters_per_second].
    pub fn set_or_clear_geodesic_meters_per_second<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.geodesic_meters_per_second = v.map(|x| x.into());
        self
    }

    /// Sets the value of [max_validation_errors][crate::model::OptimizeToursRequest::max_validation_errors].
    pub fn set_max_validation_errors<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<i32>,
    {
        self.max_validation_errors = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [max_validation_errors][crate::model::OptimizeToursRequest::max_validation_errors].
    pub fn set_or_clear_max_validation_errors<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<i32>,
    {
        self.max_validation_errors = v.map(|x| x.into());
        self
    }

    /// Sets the value of [label][crate::model::OptimizeToursRequest::label].
    pub fn set_label<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.label = v.into();
        self
    }

    /// Sets the value of [populate_travel_step_polylines][crate::model::OptimizeToursRequest::populate_travel_step_polylines].
    #[deprecated]
    pub fn set_populate_travel_step_polylines<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.populate_travel_step_polylines = v.into();
        self
    }
}

impl wkt::message::Message for OptimizeToursRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.OptimizeToursRequest"
    }
}

/// Defines additional types related to [OptimizeToursRequest].
pub mod optimize_tours_request {
    #[allow(unused_imports)]
    use super::*;

    /// Defines how the solver should handle the request. In all modes but
    /// `VALIDATE_ONLY`, if the request is invalid, you will receive an
    /// `INVALID_REQUEST` error. See
    /// [max_validation_errors][google.cloud.optimization.v1.OptimizeToursRequest.max_validation_errors]
    /// to cap the number of errors returned.
    ///
    /// [google.cloud.optimization.v1.OptimizeToursRequest.max_validation_errors]: crate::model::OptimizeToursRequest::max_validation_errors
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum SolvingMode {
        /// Solve the model.
        DefaultSolve,
        /// Only validates the model without solving it: populates as many
        /// [OptimizeToursResponse.validation_errors][google.cloud.optimization.v1.OptimizeToursResponse.validation_errors]
        /// as possible.
        ///
        /// [google.cloud.optimization.v1.OptimizeToursResponse.validation_errors]: crate::model::OptimizeToursResponse::validation_errors
        ValidateOnly,
        /// Only populates
        /// [OptimizeToursResponse.validation_errors][google.cloud.optimization.v1.OptimizeToursResponse.validation_errors]
        /// or
        /// [OptimizeToursResponse.skipped_shipments][google.cloud.optimization.v1.OptimizeToursResponse.skipped_shipments],
        /// and doesn't actually solve the rest of the request (`status` and `routes`
        /// are unset in the response).
        /// If infeasibilities in `injected_solution_constraint` routes are detected
        /// they are populated in the
        /// [OptimizeToursResponse.validation_errors][google.cloud.optimization.v1.OptimizeToursResponse.validation_errors]
        /// field and
        /// [OptimizeToursResponse.skipped_shipments][google.cloud.optimization.v1.OptimizeToursResponse.skipped_shipments]
        /// is left empty.
        ///
        /// *IMPORTANT*: not all infeasible shipments are returned here, but only the
        /// ones that are detected as infeasible during preprocessing.
        ///
        /// [google.cloud.optimization.v1.OptimizeToursResponse.skipped_shipments]: crate::model::OptimizeToursResponse::skipped_shipments
        /// [google.cloud.optimization.v1.OptimizeToursResponse.validation_errors]: crate::model::OptimizeToursResponse::validation_errors
        DetectSomeInfeasibleShipments,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [SolvingMode::value] or
        /// [SolvingMode::name].
        UnknownValue(solving_mode::UnknownValue),
    }

    #[doc(hidden)]
    pub mod solving_mode {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl SolvingMode {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::DefaultSolve => std::option::Option::Some(0),
                Self::ValidateOnly => std::option::Option::Some(1),
                Self::DetectSomeInfeasibleShipments => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::DefaultSolve => std::option::Option::Some("DEFAULT_SOLVE"),
                Self::ValidateOnly => std::option::Option::Some("VALIDATE_ONLY"),
                Self::DetectSomeInfeasibleShipments => {
                    std::option::Option::Some("DETECT_SOME_INFEASIBLE_SHIPMENTS")
                }
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for SolvingMode {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for SolvingMode {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for SolvingMode {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::DefaultSolve,
                1 => Self::ValidateOnly,
                2 => Self::DetectSomeInfeasibleShipments,
                _ => Self::UnknownValue(solving_mode::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for SolvingMode {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "DEFAULT_SOLVE" => Self::DefaultSolve,
                "VALIDATE_ONLY" => Self::ValidateOnly,
                "DETECT_SOME_INFEASIBLE_SHIPMENTS" => Self::DetectSomeInfeasibleShipments,
                _ => Self::UnknownValue(solving_mode::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for SolvingMode {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::DefaultSolve => serializer.serialize_i32(0),
                Self::ValidateOnly => serializer.serialize_i32(1),
                Self::DetectSomeInfeasibleShipments => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for SolvingMode {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<SolvingMode>::new(
                ".google.cloud.optimization.v1.OptimizeToursRequest.SolvingMode",
            ))
        }
    }

    /// Mode defining the behavior of the search, trading off latency versus
    /// solution quality. In all modes, the global request deadline is enforced.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum SearchMode {
        /// Unspecified search mode, equivalent to `RETURN_FAST`.
        Unspecified,
        /// Stop the search after finding the first good solution.
        ReturnFast,
        /// Spend all the available time to search for better solutions.
        ConsumeAllAvailableTime,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [SearchMode::value] or
        /// [SearchMode::name].
        UnknownValue(search_mode::UnknownValue),
    }

    #[doc(hidden)]
    pub mod search_mode {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl SearchMode {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::ReturnFast => std::option::Option::Some(1),
                Self::ConsumeAllAvailableTime => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("SEARCH_MODE_UNSPECIFIED"),
                Self::ReturnFast => std::option::Option::Some("RETURN_FAST"),
                Self::ConsumeAllAvailableTime => {
                    std::option::Option::Some("CONSUME_ALL_AVAILABLE_TIME")
                }
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for SearchMode {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for SearchMode {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for SearchMode {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::ReturnFast,
                2 => Self::ConsumeAllAvailableTime,
                _ => Self::UnknownValue(search_mode::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for SearchMode {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "SEARCH_MODE_UNSPECIFIED" => Self::Unspecified,
                "RETURN_FAST" => Self::ReturnFast,
                "CONSUME_ALL_AVAILABLE_TIME" => Self::ConsumeAllAvailableTime,
                _ => Self::UnknownValue(search_mode::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for SearchMode {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::ReturnFast => serializer.serialize_i32(1),
                Self::ConsumeAllAvailableTime => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for SearchMode {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<SearchMode>::new(
                ".google.cloud.optimization.v1.OptimizeToursRequest.SearchMode",
            ))
        }
    }
}

/// Response after solving a tour optimization problem containing the routes
/// followed by each vehicle, the shipments which have been skipped and the
/// overall cost of the solution.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct OptimizeToursResponse {
    /// Routes computed for each vehicle; the i-th route corresponds to the i-th
    /// vehicle in the model.
    pub routes: std::vec::Vec<crate::model::ShipmentRoute>,

    /// Copy of the
    /// [OptimizeToursRequest.label][google.cloud.optimization.v1.OptimizeToursRequest.label],
    /// if a label was specified in the request.
    ///
    /// [google.cloud.optimization.v1.OptimizeToursRequest.label]: crate::model::OptimizeToursRequest::label
    pub request_label: std::string::String,

    /// The list of all shipments skipped.
    pub skipped_shipments: std::vec::Vec<crate::model::SkippedShipment>,

    /// List of all the validation errors that we were able to detect
    /// independently. See the "MULTIPLE ERRORS" explanation for the
    /// [OptimizeToursValidationError][google.cloud.optimization.v1.OptimizeToursValidationError]
    /// message.
    ///
    /// [google.cloud.optimization.v1.OptimizeToursValidationError]: crate::model::OptimizeToursValidationError
    pub validation_errors: std::vec::Vec<crate::model::OptimizeToursValidationError>,

    /// Duration, distance and usage metrics for this solution.
    pub metrics: std::option::Option<crate::model::optimize_tours_response::Metrics>,

    /// Deprecated: Use
    /// [Metrics.total_cost][google.cloud.optimization.v1.OptimizeToursResponse.Metrics.total_cost]
    /// instead. Total cost of the solution. This takes into account all costs:
    /// costs per per hour and travel hour, fixed vehicle costs, unperformed
    /// shipment penalty costs, global duration cost, etc.
    ///
    /// [google.cloud.optimization.v1.OptimizeToursResponse.Metrics.total_cost]: crate::model::optimize_tours_response::Metrics::total_cost
    #[deprecated]
    pub total_cost: f64,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl OptimizeToursResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [routes][crate::model::OptimizeToursResponse::routes].
    pub fn set_routes<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::ShipmentRoute>,
    {
        use std::iter::Iterator;
        self.routes = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [request_label][crate::model::OptimizeToursResponse::request_label].
    pub fn set_request_label<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.request_label = v.into();
        self
    }

    /// Sets the value of [skipped_shipments][crate::model::OptimizeToursResponse::skipped_shipments].
    pub fn set_skipped_shipments<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::SkippedShipment>,
    {
        use std::iter::Iterator;
        self.skipped_shipments = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [validation_errors][crate::model::OptimizeToursResponse::validation_errors].
    pub fn set_validation_errors<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::OptimizeToursValidationError>,
    {
        use std::iter::Iterator;
        self.validation_errors = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [metrics][crate::model::OptimizeToursResponse::metrics].
    pub fn set_metrics<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::optimize_tours_response::Metrics>,
    {
        self.metrics = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [metrics][crate::model::OptimizeToursResponse::metrics].
    pub fn set_or_clear_metrics<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::optimize_tours_response::Metrics>,
    {
        self.metrics = v.map(|x| x.into());
        self
    }

    /// Sets the value of [total_cost][crate::model::OptimizeToursResponse::total_cost].
    #[deprecated]
    pub fn set_total_cost<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.total_cost = v.into();
        self
    }
}

impl wkt::message::Message for OptimizeToursResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.OptimizeToursResponse"
    }
}

/// Defines additional types related to [OptimizeToursResponse].
pub mod optimize_tours_response {
    #[allow(unused_imports)]
    use super::*;

    /// Overall metrics, aggregated over all routes.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct Metrics {
        /// Aggregated over the routes. Each metric is the sum (or max, for loads)
        /// over all
        /// [ShipmentRoute.metrics][google.cloud.optimization.v1.ShipmentRoute.metrics]
        /// fields of the same name.
        ///
        /// [google.cloud.optimization.v1.ShipmentRoute.metrics]: crate::model::ShipmentRoute::metrics
        pub aggregated_route_metrics: std::option::Option<crate::model::AggregatedMetrics>,

        /// Number of mandatory shipments skipped.
        pub skipped_mandatory_shipment_count: i32,

        /// Number of vehicles used. Note: if a vehicle route is empty and
        /// [Vehicle.used_if_route_is_empty][google.cloud.optimization.v1.Vehicle.used_if_route_is_empty]
        /// is true, the vehicle is considered used.
        ///
        /// [google.cloud.optimization.v1.Vehicle.used_if_route_is_empty]: crate::model::Vehicle::used_if_route_is_empty
        pub used_vehicle_count: i32,

        /// The earliest start time for a used vehicle, computed as the minimum over
        /// all used vehicles of
        /// [ShipmentRoute.vehicle_start_time][google.cloud.optimization.v1.ShipmentRoute.vehicle_start_time].
        ///
        /// [google.cloud.optimization.v1.ShipmentRoute.vehicle_start_time]: crate::model::ShipmentRoute::vehicle_start_time
        pub earliest_vehicle_start_time: std::option::Option<wkt::Timestamp>,

        /// The latest end time for a used vehicle, computed as the maximum over all
        /// used vehicles of
        /// [ShipmentRoute.vehicle_end_time][google.cloud.optimization.v1.ShipmentRoute.vehicle_end_time].
        ///
        /// [google.cloud.optimization.v1.ShipmentRoute.vehicle_end_time]: crate::model::ShipmentRoute::vehicle_end_time
        pub latest_vehicle_end_time: std::option::Option<wkt::Timestamp>,

        /// Cost of the solution, broken down by cost-related request fields.
        /// The keys are proto paths, relative to the input OptimizeToursRequest,
        /// e.g. "model.shipments.pickups.cost", and the values are the total cost
        /// generated by the corresponding cost field, aggregated over the whole
        /// solution. In other words, costs["model.shipments.pickups.cost"] is the
        /// sum of all pickup costs over the solution. All costs defined in the model
        /// are reported in detail here with the exception of costs related to
        /// TransitionAttributes that are only reported in an aggregated way as of
        /// 2022/01.
        pub costs: std::collections::HashMap<std::string::String, f64>,

        /// Total cost of the solution. The sum of all values in the costs map.
        pub total_cost: f64,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Metrics {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [aggregated_route_metrics][crate::model::optimize_tours_response::Metrics::aggregated_route_metrics].
        pub fn set_aggregated_route_metrics<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::AggregatedMetrics>,
        {
            self.aggregated_route_metrics = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [aggregated_route_metrics][crate::model::optimize_tours_response::Metrics::aggregated_route_metrics].
        pub fn set_or_clear_aggregated_route_metrics<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::AggregatedMetrics>,
        {
            self.aggregated_route_metrics = v.map(|x| x.into());
            self
        }

        /// Sets the value of [skipped_mandatory_shipment_count][crate::model::optimize_tours_response::Metrics::skipped_mandatory_shipment_count].
        pub fn set_skipped_mandatory_shipment_count<T: std::convert::Into<i32>>(
            mut self,
            v: T,
        ) -> Self {
            self.skipped_mandatory_shipment_count = v.into();
            self
        }

        /// Sets the value of [used_vehicle_count][crate::model::optimize_tours_response::Metrics::used_vehicle_count].
        pub fn set_used_vehicle_count<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
            self.used_vehicle_count = v.into();
            self
        }

        /// Sets the value of [earliest_vehicle_start_time][crate::model::optimize_tours_response::Metrics::earliest_vehicle_start_time].
        pub fn set_earliest_vehicle_start_time<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.earliest_vehicle_start_time = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [earliest_vehicle_start_time][crate::model::optimize_tours_response::Metrics::earliest_vehicle_start_time].
        pub fn set_or_clear_earliest_vehicle_start_time<T>(
            mut self,
            v: std::option::Option<T>,
        ) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.earliest_vehicle_start_time = v.map(|x| x.into());
            self
        }

        /// Sets the value of [latest_vehicle_end_time][crate::model::optimize_tours_response::Metrics::latest_vehicle_end_time].
        pub fn set_latest_vehicle_end_time<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.latest_vehicle_end_time = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [latest_vehicle_end_time][crate::model::optimize_tours_response::Metrics::latest_vehicle_end_time].
        pub fn set_or_clear_latest_vehicle_end_time<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.latest_vehicle_end_time = v.map(|x| x.into());
            self
        }

        /// Sets the value of [costs][crate::model::optimize_tours_response::Metrics::costs].
        pub fn set_costs<T, K, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = (K, V)>,
            K: std::convert::Into<std::string::String>,
            V: std::convert::Into<f64>,
        {
            use std::iter::Iterator;
            self.costs = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
            self
        }

        /// Sets the value of [total_cost][crate::model::optimize_tours_response::Metrics::total_cost].
        pub fn set_total_cost<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
            self.total_cost = v.into();
            self
        }
    }

    impl wkt::message::Message for Metrics {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.OptimizeToursResponse.Metrics"
        }
    }
}

/// Request to batch optimize tours as an asynchronous operation.
/// Each input file should contain one `OptimizeToursRequest`, and each output
/// file will contain one `OptimizeToursResponse`. The request contains
/// information to read/write and parse the files. All the input and output files
/// should be under the same project.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BatchOptimizeToursRequest {
    /// Required. Target project and location to make a call.
    ///
    /// Format: `projects/{project-id}/locations/{location-id}`.
    ///
    /// If no location is specified, a region will be chosen automatically.
    pub parent: std::string::String,

    /// Required. Input/Output information each purchase model, such as file paths
    /// and data formats.
    pub model_configs: std::vec::Vec<crate::model::batch_optimize_tours_request::AsyncModelConfig>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BatchOptimizeToursRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::BatchOptimizeToursRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [model_configs][crate::model::BatchOptimizeToursRequest::model_configs].
    pub fn set_model_configs<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::batch_optimize_tours_request::AsyncModelConfig>,
    {
        use std::iter::Iterator;
        self.model_configs = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for BatchOptimizeToursRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.BatchOptimizeToursRequest"
    }
}

/// Defines additional types related to [BatchOptimizeToursRequest].
pub mod batch_optimize_tours_request {
    #[allow(unused_imports)]
    use super::*;

    /// Information for solving one optimization model asynchronously.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct AsyncModelConfig {
        /// User defined model name, can be used as alias by users to keep track of
        /// models.
        pub display_name: std::string::String,

        /// Required. Information about the input model.
        pub input_config: std::option::Option<crate::model::InputConfig>,

        /// Required. The desired output location information.
        pub output_config: std::option::Option<crate::model::OutputConfig>,

        /// If this is set, the model will be solved in the checkpoint mode. In this
        /// mode, the input model can have a deadline longer than 30 mins without the
        /// risk of interruption. The model will be solved in multiple short-running
        /// stages. Each stage generates an intermediate checkpoint
        /// and stores it in the user's Cloud Storage buckets. The checkpoint
        /// mode should be preferred over
        /// allow_large_deadline_despite_interruption_risk since it prevents the risk
        /// of interruption.
        pub enable_checkpoints: bool,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl AsyncModelConfig {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [display_name][crate::model::batch_optimize_tours_request::AsyncModelConfig::display_name].
        pub fn set_display_name<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.display_name = v.into();
            self
        }

        /// Sets the value of [input_config][crate::model::batch_optimize_tours_request::AsyncModelConfig::input_config].
        pub fn set_input_config<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::InputConfig>,
        {
            self.input_config = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [input_config][crate::model::batch_optimize_tours_request::AsyncModelConfig::input_config].
        pub fn set_or_clear_input_config<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::InputConfig>,
        {
            self.input_config = v.map(|x| x.into());
            self
        }

        /// Sets the value of [output_config][crate::model::batch_optimize_tours_request::AsyncModelConfig::output_config].
        pub fn set_output_config<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::OutputConfig>,
        {
            self.output_config = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [output_config][crate::model::batch_optimize_tours_request::AsyncModelConfig::output_config].
        pub fn set_or_clear_output_config<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::OutputConfig>,
        {
            self.output_config = v.map(|x| x.into());
            self
        }

        /// Sets the value of [enable_checkpoints][crate::model::batch_optimize_tours_request::AsyncModelConfig::enable_checkpoints].
        pub fn set_enable_checkpoints<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
            self.enable_checkpoints = v.into();
            self
        }
    }

    impl wkt::message::Message for AsyncModelConfig {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.BatchOptimizeToursRequest.AsyncModelConfig"
        }
    }
}

/// Response to a `BatchOptimizeToursRequest`. This is returned in
/// the LRO Operation after the operation is complete.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BatchOptimizeToursResponse {
    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BatchOptimizeToursResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }
}

impl wkt::message::Message for BatchOptimizeToursResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.BatchOptimizeToursResponse"
    }
}

/// A shipment model contains a set of shipments which must be performed by a
/// set of vehicles, while minimizing the overall cost, which is the sum of:
///
/// * the cost of routing the vehicles (sum of cost per total time, cost per
///   travel time, and fixed cost over all vehicles).
/// * the unperformed shipment penalties.
/// * the cost of the global duration of the shipments
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ShipmentModel {
    /// Set of shipments which must be performed in the model.
    pub shipments: std::vec::Vec<crate::model::Shipment>,

    /// Set of vehicles which can be used to perform visits.
    pub vehicles: std::vec::Vec<crate::model::Vehicle>,

    /// Constrains the maximum number of active vehicles. A vehicle is active if
    /// its route performs at least one shipment. This can be used to limit the
    /// number of routes in the case where there are fewer drivers than
    /// vehicles and that the fleet of vehicles is heterogeneous. The optimization
    /// will then select the best subset of vehicles to use.
    /// Must be strictly positive.
    pub max_active_vehicles: std::option::Option<i32>,

    /// Global start and end time of the model: no times outside of this range
    /// can be considered valid.
    ///
    /// The model's time span must be less than a year, i.e. the `global_end_time`
    /// and the `global_start_time` must be within 31536000 seconds of each other.
    ///
    /// When using `cost_per_*hour` fields, you might want to set this window to a
    /// smaller interval to increase performance (eg. if you model a single day,
    /// you should set the global time limits to that day).
    /// If unset, 00:00:00 UTC, January 1, 1970 (i.e. seconds: 0, nanos: 0) is used
    /// as default.
    pub global_start_time: std::option::Option<wkt::Timestamp>,

    /// If unset, 00:00:00 UTC, January 1, 1971 (i.e. seconds: 31536000, nanos: 0)
    /// is used as default.
    pub global_end_time: std::option::Option<wkt::Timestamp>,

    /// The "global duration" of the overall plan is the difference between the
    /// earliest effective start time and the latest effective end time of
    /// all vehicles. Users can assign a cost per hour to that quantity to try
    /// and optimize for earliest job completion, for example. This cost must be in
    /// the same unit as
    /// [Shipment.penalty_cost][google.cloud.optimization.v1.Shipment.penalty_cost].
    ///
    /// [google.cloud.optimization.v1.Shipment.penalty_cost]: crate::model::Shipment::penalty_cost
    pub global_duration_cost_per_hour: f64,

    /// Specifies duration and distance matrices used in the model. If this field
    /// is empty, Google Maps or geodesic distances will be used instead, depending
    /// on the value of the `use_geodesic_distances` field. If it is not empty,
    /// `use_geodesic_distances` cannot be true and neither
    /// `duration_distance_matrix_src_tags` nor `duration_distance_matrix_dst_tags`
    /// can be empty.
    ///
    /// Usage examples:
    ///
    /// * There are two locations: locA and locB.
    /// * 1 vehicle starting its route at locA and ending it at locA.
    /// * 1 pickup visit request at locB.
    ///
    /// ```norust
    /// model {
    ///   vehicles { start_tags: "locA"  end_tags: "locA" }
    ///   shipments { pickups { tags: "locB" } }
    ///   duration_distance_matrix_src_tags: "locA"
    ///   duration_distance_matrix_src_tags: "locB"
    ///   duration_distance_matrix_dst_tags: "locA"
    ///   duration_distance_matrix_dst_tags: "locB"
    ///   duration_distance_matrices {
    ///     rows {  # from: locA
    ///       durations { seconds: 0 }   meters: 0    # to: locA
    ///       durations { seconds: 100 } meters: 1000 # to: locB
    ///     }
    ///     rows {  # from: locB
    ///       durations { seconds: 102 } meters: 990 # to: locA
    ///       durations { seconds: 0 }   meters: 0   # to: locB
    ///     }
    ///   }
    /// }
    /// ```
    ///
    /// * There are three locations: locA, locB and locC.
    /// * 1 vehicle starting its route at locA and ending it at locB, using
    ///   matrix "fast".
    /// * 1 vehicle starting its route at locB and ending it at locB, using
    ///   matrix "slow".
    /// * 1 vehicle starting its route at locB and ending it at locB, using
    ///   matrix "fast".
    /// * 1 pickup visit request at locC.
    ///
    /// ```norust
    /// model {
    ///   vehicles { start_tags: "locA" end_tags: "locB" start_tags: "fast" }
    ///   vehicles { start_tags: "locB" end_tags: "locB" start_tags: "slow" }
    ///   vehicles { start_tags: "locB" end_tags: "locB" start_tags: "fast" }
    ///   shipments { pickups { tags: "locC" } }
    ///   duration_distance_matrix_src_tags: "locA"
    ///   duration_distance_matrix_src_tags: "locB"
    ///   duration_distance_matrix_src_tags: "locC"
    ///   duration_distance_matrix_dst_tags: "locB"
    ///   duration_distance_matrix_dst_tags: "locC"
    ///   duration_distance_matrices {
    ///     vehicle_start_tag: "fast"
    ///     rows {  # from: locA
    ///       durations { seconds: 1000 } meters: 2000 # to: locB
    ///       durations { seconds: 600 }  meters: 1000 # to: locC
    ///     }
    ///     rows {  # from: locB
    ///       durations { seconds: 0 }   meters: 0    # to: locB
    ///       durations { seconds: 700 } meters: 1200 # to: locC
    ///     }
    ///     rows {  # from: locC
    ///       durations { seconds: 702 } meters: 1190 # to: locB
    ///       durations { seconds: 0 }   meters: 0    # to: locC
    ///     }
    ///   }
    ///   duration_distance_matrices {
    ///     vehicle_start_tag: "slow"
    ///     rows {  # from: locA
    ///       durations { seconds: 1800 } meters: 2001 # to: locB
    ///       durations { seconds: 900 }  meters: 1002 # to: locC
    ///     }
    ///     rows {  # from: locB
    ///       durations { seconds: 0 }    meters: 0    # to: locB
    ///       durations { seconds: 1000 } meters: 1202 # to: locC
    ///     }
    ///     rows {  # from: locC
    ///       durations { seconds: 1001 } meters: 1195 # to: locB
    ///       durations { seconds: 0 }    meters: 0    # to: locC
    ///     }
    ///   }
    /// }
    /// ```
    pub duration_distance_matrices:
        std::vec::Vec<crate::model::shipment_model::DurationDistanceMatrix>,

    /// Tags defining the sources of the duration and distance matrices;
    /// `duration_distance_matrices(i).rows(j)` defines durations and distances
    /// from visits with tag `duration_distance_matrix_src_tags(j)` to other visits
    /// in matrix i.
    ///
    /// Tags correspond to
    /// [VisitRequest.tags][google.cloud.optimization.v1.Shipment.VisitRequest.tags]
    /// or [Vehicle.start_tags][google.cloud.optimization.v1.Vehicle.start_tags].
    /// A given `VisitRequest` or `Vehicle` must match exactly one tag in this
    /// field. Note that a `Vehicle`'s source, destination and matrix tags may be
    /// the same; similarly a `VisitRequest`'s source and destination tags may be
    /// the same. All tags must be different and cannot be empty strings. If this
    /// field is not empty, then `duration_distance_matrices` must not be empty.
    ///
    /// [google.cloud.optimization.v1.Shipment.VisitRequest.tags]: crate::model::shipment::VisitRequest::tags
    /// [google.cloud.optimization.v1.Vehicle.start_tags]: crate::model::Vehicle::start_tags
    pub duration_distance_matrix_src_tags: std::vec::Vec<std::string::String>,

    /// Tags defining the destinations of the duration and distance matrices;
    /// `duration_distance_matrices(i).rows(j).durations(k)` (resp.
    /// `duration_distance_matrices(i).rows(j).meters(k))` defines the duration
    /// (resp. the distance) of the travel from visits with tag
    /// `duration_distance_matrix_src_tags(j)` to visits with tag
    /// `duration_distance_matrix_dst_tags(k)` in matrix i.
    ///
    /// Tags correspond to
    /// [VisitRequest.tags][google.cloud.optimization.v1.Shipment.VisitRequest.tags]
    /// or [Vehicle.start_tags][google.cloud.optimization.v1.Vehicle.start_tags].
    /// A given `VisitRequest` or `Vehicle` must match exactly one tag in this
    /// field. Note that a `Vehicle`'s source, destination and matrix tags may be
    /// the same; similarly a `VisitRequest`'s source and destination tags may be
    /// the same. All tags must be different and cannot be empty strings. If this
    /// field is not empty, then `duration_distance_matrices` must not be empty.
    ///
    /// [google.cloud.optimization.v1.Shipment.VisitRequest.tags]: crate::model::shipment::VisitRequest::tags
    /// [google.cloud.optimization.v1.Vehicle.start_tags]: crate::model::Vehicle::start_tags
    pub duration_distance_matrix_dst_tags: std::vec::Vec<std::string::String>,

    /// Transition attributes added to the model.
    pub transition_attributes: std::vec::Vec<crate::model::TransitionAttributes>,

    /// Sets of incompatible shipment_types (see `ShipmentTypeIncompatibility`).
    pub shipment_type_incompatibilities: std::vec::Vec<crate::model::ShipmentTypeIncompatibility>,

    /// Sets of `shipment_type` requirements (see `ShipmentTypeRequirement`).
    pub shipment_type_requirements: std::vec::Vec<crate::model::ShipmentTypeRequirement>,

    /// Set of precedence rules which must be enforced in the model.
    pub precedence_rules: std::vec::Vec<crate::model::shipment_model::PrecedenceRule>,

    /// Deprecated: No longer used.
    /// Set of break rules used in the model.
    /// Each vehicle specifies the `BreakRule` that applies to it via the
    /// [Vehicle.break_rule_indices][google.cloud.optimization.v1.Vehicle.break_rule_indices]
    /// field (which must be a singleton).
    ///
    /// [google.cloud.optimization.v1.Vehicle.break_rule_indices]: crate::model::Vehicle::break_rule_indices
    #[deprecated]
    pub break_rules: std::vec::Vec<crate::model::shipment_model::BreakRule>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ShipmentModel {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [shipments][crate::model::ShipmentModel::shipments].
    pub fn set_shipments<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Shipment>,
    {
        use std::iter::Iterator;
        self.shipments = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [vehicles][crate::model::ShipmentModel::vehicles].
    pub fn set_vehicles<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Vehicle>,
    {
        use std::iter::Iterator;
        self.vehicles = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [max_active_vehicles][crate::model::ShipmentModel::max_active_vehicles].
    pub fn set_max_active_vehicles<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<i32>,
    {
        self.max_active_vehicles = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [max_active_vehicles][crate::model::ShipmentModel::max_active_vehicles].
    pub fn set_or_clear_max_active_vehicles<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<i32>,
    {
        self.max_active_vehicles = v.map(|x| x.into());
        self
    }

    /// Sets the value of [global_start_time][crate::model::ShipmentModel::global_start_time].
    pub fn set_global_start_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.global_start_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [global_start_time][crate::model::ShipmentModel::global_start_time].
    pub fn set_or_clear_global_start_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.global_start_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [global_end_time][crate::model::ShipmentModel::global_end_time].
    pub fn set_global_end_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.global_end_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [global_end_time][crate::model::ShipmentModel::global_end_time].
    pub fn set_or_clear_global_end_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.global_end_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [global_duration_cost_per_hour][crate::model::ShipmentModel::global_duration_cost_per_hour].
    pub fn set_global_duration_cost_per_hour<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.global_duration_cost_per_hour = v.into();
        self
    }

    /// Sets the value of [duration_distance_matrices][crate::model::ShipmentModel::duration_distance_matrices].
    pub fn set_duration_distance_matrices<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::shipment_model::DurationDistanceMatrix>,
    {
        use std::iter::Iterator;
        self.duration_distance_matrices = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [duration_distance_matrix_src_tags][crate::model::ShipmentModel::duration_distance_matrix_src_tags].
    pub fn set_duration_distance_matrix_src_tags<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.duration_distance_matrix_src_tags = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [duration_distance_matrix_dst_tags][crate::model::ShipmentModel::duration_distance_matrix_dst_tags].
    pub fn set_duration_distance_matrix_dst_tags<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.duration_distance_matrix_dst_tags = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [transition_attributes][crate::model::ShipmentModel::transition_attributes].
    pub fn set_transition_attributes<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::TransitionAttributes>,
    {
        use std::iter::Iterator;
        self.transition_attributes = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [shipment_type_incompatibilities][crate::model::ShipmentModel::shipment_type_incompatibilities].
    pub fn set_shipment_type_incompatibilities<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::ShipmentTypeIncompatibility>,
    {
        use std::iter::Iterator;
        self.shipment_type_incompatibilities = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [shipment_type_requirements][crate::model::ShipmentModel::shipment_type_requirements].
    pub fn set_shipment_type_requirements<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::ShipmentTypeRequirement>,
    {
        use std::iter::Iterator;
        self.shipment_type_requirements = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [precedence_rules][crate::model::ShipmentModel::precedence_rules].
    pub fn set_precedence_rules<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::shipment_model::PrecedenceRule>,
    {
        use std::iter::Iterator;
        self.precedence_rules = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [break_rules][crate::model::ShipmentModel::break_rules].
    #[deprecated]
    pub fn set_break_rules<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::shipment_model::BreakRule>,
    {
        use std::iter::Iterator;
        self.break_rules = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for ShipmentModel {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.ShipmentModel"
    }
}

/// Defines additional types related to [ShipmentModel].
pub mod shipment_model {
    #[allow(unused_imports)]
    use super::*;

    /// Specifies a duration and distance matrix from visit and vehicle start
    /// locations to visit and vehicle end locations.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct DurationDistanceMatrix {
        /// Specifies the rows of the duration and distance matrix. It must have as
        /// many elements as
        /// [ShipmentModel.duration_distance_matrix_src_tags][google.cloud.optimization.v1.ShipmentModel.duration_distance_matrix_src_tags].
        ///
        /// [google.cloud.optimization.v1.ShipmentModel.duration_distance_matrix_src_tags]: crate::model::ShipmentModel::duration_distance_matrix_src_tags
        pub rows: std::vec::Vec<crate::model::shipment_model::duration_distance_matrix::Row>,

        /// Tag defining to which vehicles this duration and distance matrix applies.
        /// If empty, this applies to all vehicles, and there can only be a single
        /// matrix.
        ///
        /// Each vehicle start must match exactly one matrix, i.e. exactly one of
        /// their `start_tags` field must match the `vehicle_start_tag` of a matrix
        /// (and of that matrix only).
        ///
        /// All matrices must have a different `vehicle_start_tag`.
        pub vehicle_start_tag: std::string::String,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl DurationDistanceMatrix {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [rows][crate::model::shipment_model::DurationDistanceMatrix::rows].
        pub fn set_rows<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::shipment_model::duration_distance_matrix::Row>,
        {
            use std::iter::Iterator;
            self.rows = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [vehicle_start_tag][crate::model::shipment_model::DurationDistanceMatrix::vehicle_start_tag].
        pub fn set_vehicle_start_tag<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.vehicle_start_tag = v.into();
            self
        }
    }

    impl wkt::message::Message for DurationDistanceMatrix {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.ShipmentModel.DurationDistanceMatrix"
        }
    }

    /// Defines additional types related to [DurationDistanceMatrix].
    pub mod duration_distance_matrix {
        #[allow(unused_imports)]
        use super::*;

        /// Specifies a row of the duration and distance matrix.
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct Row {
            /// Duration values for a given row. It must have as many elements as
            /// [ShipmentModel.duration_distance_matrix_dst_tags][google.cloud.optimization.v1.ShipmentModel.duration_distance_matrix_dst_tags].
            ///
            /// [google.cloud.optimization.v1.ShipmentModel.duration_distance_matrix_dst_tags]: crate::model::ShipmentModel::duration_distance_matrix_dst_tags
            pub durations: std::vec::Vec<wkt::Duration>,

            /// Distance values for a given row. If no costs or constraints refer to
            /// distances in the model, this can be left empty; otherwise it must have
            /// as many elements as `durations`.
            pub meters: std::vec::Vec<f64>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl Row {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [durations][crate::model::shipment_model::duration_distance_matrix::Row::durations].
            pub fn set_durations<T, V>(mut self, v: T) -> Self
            where
                T: std::iter::IntoIterator<Item = V>,
                V: std::convert::Into<wkt::Duration>,
            {
                use std::iter::Iterator;
                self.durations = v.into_iter().map(|i| i.into()).collect();
                self
            }

            /// Sets the value of [meters][crate::model::shipment_model::duration_distance_matrix::Row::meters].
            pub fn set_meters<T, V>(mut self, v: T) -> Self
            where
                T: std::iter::IntoIterator<Item = V>,
                V: std::convert::Into<f64>,
            {
                use std::iter::Iterator;
                self.meters = v.into_iter().map(|i| i.into()).collect();
                self
            }
        }

        impl wkt::message::Message for Row {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.optimization.v1.ShipmentModel.DurationDistanceMatrix.Row"
            }
        }
    }

    /// A precedence rule between two events (each event is the pickup or the
    /// delivery of a shipment): the "second" event has to start at least
    /// `offset_duration` after "first" has started.
    ///
    /// Several precedences can refer to the same (or related) events, e.g.,
    /// "pickup of B happens after delivery of A" and "pickup of C happens after
    /// pickup of B".
    ///
    /// Furthermore, precedences only apply when both shipments are performed and
    /// are otherwise ignored.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct PrecedenceRule {
        /// Shipment index of the "first" event. This field must be specified.
        pub first_index: std::option::Option<i32>,

        /// Indicates if the "first" event is a delivery.
        pub first_is_delivery: bool,

        /// Shipment index of the "second" event. This field must be specified.
        pub second_index: std::option::Option<i32>,

        /// Indicates if the "second" event is a delivery.
        pub second_is_delivery: bool,

        /// The offset between the "first" and "second" event. It can be negative.
        pub offset_duration: std::option::Option<wkt::Duration>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl PrecedenceRule {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [first_index][crate::model::shipment_model::PrecedenceRule::first_index].
        pub fn set_first_index<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<i32>,
        {
            self.first_index = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [first_index][crate::model::shipment_model::PrecedenceRule::first_index].
        pub fn set_or_clear_first_index<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<i32>,
        {
            self.first_index = v.map(|x| x.into());
            self
        }

        /// Sets the value of [first_is_delivery][crate::model::shipment_model::PrecedenceRule::first_is_delivery].
        pub fn set_first_is_delivery<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
            self.first_is_delivery = v.into();
            self
        }

        /// Sets the value of [second_index][crate::model::shipment_model::PrecedenceRule::second_index].
        pub fn set_second_index<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<i32>,
        {
            self.second_index = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [second_index][crate::model::shipment_model::PrecedenceRule::second_index].
        pub fn set_or_clear_second_index<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<i32>,
        {
            self.second_index = v.map(|x| x.into());
            self
        }

        /// Sets the value of [second_is_delivery][crate::model::shipment_model::PrecedenceRule::second_is_delivery].
        pub fn set_second_is_delivery<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
            self.second_is_delivery = v.into();
            self
        }

        /// Sets the value of [offset_duration][crate::model::shipment_model::PrecedenceRule::offset_duration].
        pub fn set_offset_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.offset_duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [offset_duration][crate::model::shipment_model::PrecedenceRule::offset_duration].
        pub fn set_or_clear_offset_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.offset_duration = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for PrecedenceRule {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.ShipmentModel.PrecedenceRule"
        }
    }

    /// Deprecated: Use top level
    /// [BreakRule][google.cloud.optimization.v1.ShipmentModel.BreakRule] instead.
    /// Rules to generate time breaks for a vehicle (e.g. lunch
    /// breaks). A break is a contiguous period of time during which the vehicle
    /// remains idle at its current position and cannot perform any visit. A break
    /// may occur:
    ///
    /// * during the travel between two visits (which includes the time right
    ///   before or right after a visit, but not in the middle of a visit), in
    ///   which case it extends the corresponding transit time between the visits
    /// * before the vehicle start (the vehicle may not start in the middle of
    ///   a break), in which case it does not affect the vehicle start time.
    /// * after the vehicle end (ditto, with the vehicle end time).
    ///
    /// [google.cloud.optimization.v1.ShipmentModel.BreakRule]: crate::model::shipment_model::BreakRule
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    #[deprecated]
    pub struct BreakRule {
        /// Sequence of breaks. See the `BreakRequest` message.
        pub break_requests: std::vec::Vec<crate::model::shipment_model::break_rule::BreakRequest>,

        /// Several `FrequencyConstraint` may apply. They must all be satisfied by
        /// the `BreakRequest`s of this `BreakRule`. See `FrequencyConstraint`.
        pub frequency_constraints:
            std::vec::Vec<crate::model::shipment_model::break_rule::FrequencyConstraint>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl BreakRule {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [break_requests][crate::model::shipment_model::BreakRule::break_requests].
        pub fn set_break_requests<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::shipment_model::break_rule::BreakRequest>,
        {
            use std::iter::Iterator;
            self.break_requests = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [frequency_constraints][crate::model::shipment_model::BreakRule::frequency_constraints].
        pub fn set_frequency_constraints<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::shipment_model::break_rule::FrequencyConstraint>,
        {
            use std::iter::Iterator;
            self.frequency_constraints = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for BreakRule {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.ShipmentModel.BreakRule"
        }
    }

    /// Defines additional types related to [BreakRule].
    pub mod break_rule {
        #[allow(unused_imports)]
        use super::*;

        /// The sequence of breaks (i.e. their number and order) that apply to each
        /// vehicle must be known beforehand. The repeated `BreakRequest`s define
        /// that sequence, in the order in which they must occur. Their time windows
        /// (`earliest_start_time` / `latest_start_time`) may overlap, but they must
        /// be compatible with the order (this is checked).
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct BreakRequest {
            /// Required. Lower bound (inclusive) on the start of the break.
            pub earliest_start_time: std::option::Option<wkt::Timestamp>,

            /// Required. Upper bound (inclusive) on the start of the break.
            pub latest_start_time: std::option::Option<wkt::Timestamp>,

            /// Required. Minimum duration of the break. Must be positive.
            pub min_duration: std::option::Option<wkt::Duration>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl BreakRequest {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [earliest_start_time][crate::model::shipment_model::break_rule::BreakRequest::earliest_start_time].
            pub fn set_earliest_start_time<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<wkt::Timestamp>,
            {
                self.earliest_start_time = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [earliest_start_time][crate::model::shipment_model::break_rule::BreakRequest::earliest_start_time].
            pub fn set_or_clear_earliest_start_time<T>(mut self, v: std::option::Option<T>) -> Self
            where
                T: std::convert::Into<wkt::Timestamp>,
            {
                self.earliest_start_time = v.map(|x| x.into());
                self
            }

            /// Sets the value of [latest_start_time][crate::model::shipment_model::break_rule::BreakRequest::latest_start_time].
            pub fn set_latest_start_time<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<wkt::Timestamp>,
            {
                self.latest_start_time = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [latest_start_time][crate::model::shipment_model::break_rule::BreakRequest::latest_start_time].
            pub fn set_or_clear_latest_start_time<T>(mut self, v: std::option::Option<T>) -> Self
            where
                T: std::convert::Into<wkt::Timestamp>,
            {
                self.latest_start_time = v.map(|x| x.into());
                self
            }

            /// Sets the value of [min_duration][crate::model::shipment_model::break_rule::BreakRequest::min_duration].
            pub fn set_min_duration<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<wkt::Duration>,
            {
                self.min_duration = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [min_duration][crate::model::shipment_model::break_rule::BreakRequest::min_duration].
            pub fn set_or_clear_min_duration<T>(mut self, v: std::option::Option<T>) -> Self
            where
                T: std::convert::Into<wkt::Duration>,
            {
                self.min_duration = v.map(|x| x.into());
                self
            }
        }

        impl wkt::message::Message for BreakRequest {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.optimization.v1.ShipmentModel.BreakRule.BreakRequest"
            }
        }

        /// One may further constrain the frequency and duration of the breaks
        /// specified above, by enforcing a minimum break frequency, such as
        /// "There must be a break of at least 1 hour every 12 hours". Assuming that
        /// this can be interpreted as "Within any sliding time window of 12h, there
        /// must be at least one break of at least one hour", that example would
        /// translate to the following `FrequencyConstraint`:
        ///
        /// ```norust
        /// {
        ///    min_break_duration { seconds: 3600 }         # 1 hour.
        ///    max_inter_break_duration { seconds: 39600 }  # 11 hours (12 - 1 = 11).
        /// }
        /// ```
        ///
        /// The timing and duration of the breaks in the solution will respect all
        /// such constraints, in addition to the time windows and minimum durations
        /// already specified in the `BreakRequest`.
        ///
        /// A `FrequencyConstraint` may in practice apply to non-consecutive breaks.
        /// For example, the following schedule honors the "1h every 12h" example:
        ///
        /// ```norust
        ///   04:00 vehicle start
        ///    .. performing travel and visits ..
        ///   09:00 1 hour break
        ///   10:00 end of the break
        ///    .. performing travel and visits ..
        ///   12:00 20-min lunch break
        ///   12:20 end of the break
        ///    .. performing travel and visits ..
        ///   21:00 1 hour break
        ///   22:00 end of the break
        ///    .. performing travel and visits ..
        ///   23:59 vehicle end
        /// ```
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct FrequencyConstraint {
            /// Required. Minimum break duration for this constraint. Nonnegative.
            /// See description of `FrequencyConstraint`.
            pub min_break_duration: std::option::Option<wkt::Duration>,

            /// Required. Maximum allowed span of any interval of time in the route
            /// that does not include at least partially a break of `duration >=
            /// min_break_duration`. Must be positive.
            pub max_inter_break_duration: std::option::Option<wkt::Duration>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl FrequencyConstraint {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [min_break_duration][crate::model::shipment_model::break_rule::FrequencyConstraint::min_break_duration].
            pub fn set_min_break_duration<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<wkt::Duration>,
            {
                self.min_break_duration = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [min_break_duration][crate::model::shipment_model::break_rule::FrequencyConstraint::min_break_duration].
            pub fn set_or_clear_min_break_duration<T>(mut self, v: std::option::Option<T>) -> Self
            where
                T: std::convert::Into<wkt::Duration>,
            {
                self.min_break_duration = v.map(|x| x.into());
                self
            }

            /// Sets the value of [max_inter_break_duration][crate::model::shipment_model::break_rule::FrequencyConstraint::max_inter_break_duration].
            pub fn set_max_inter_break_duration<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<wkt::Duration>,
            {
                self.max_inter_break_duration = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [max_inter_break_duration][crate::model::shipment_model::break_rule::FrequencyConstraint::max_inter_break_duration].
            pub fn set_or_clear_max_inter_break_duration<T>(
                mut self,
                v: std::option::Option<T>,
            ) -> Self
            where
                T: std::convert::Into<wkt::Duration>,
            {
                self.max_inter_break_duration = v.map(|x| x.into());
                self
            }
        }

        impl wkt::message::Message for FrequencyConstraint {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.optimization.v1.ShipmentModel.BreakRule.FrequencyConstraint"
            }
        }
    }
}

/// The shipment of a single item, from one of its pickups to one of its
/// deliveries. For the shipment to be considered as performed, a unique vehicle
/// must visit one of its pickup locations (and decrease its spare capacities
/// accordingly), then visit one of its delivery locations later on (and
/// therefore re-increase its spare capacities accordingly).
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Shipment {
    /// Set of pickup alternatives associated to the shipment. If not specified,
    /// the vehicle only needs to visit a location corresponding to the deliveries.
    pub pickups: std::vec::Vec<crate::model::shipment::VisitRequest>,

    /// Set of delivery alternatives associated to the shipment. If not specified,
    /// the vehicle only needs to visit a location corresponding to the pickups.
    pub deliveries: std::vec::Vec<crate::model::shipment::VisitRequest>,

    /// Load demands of the shipment (for example weight, volume, number of
    /// pallets etc). The keys in the map should be identifiers describing the type
    /// of the corresponding load, ideally also including the units.
    /// For example: "weight_kg", "volume_gallons", "pallet_count", etc.
    /// If a given key does not appear in the map, the corresponding load is
    /// considered as null.
    pub load_demands: std::collections::HashMap<std::string::String, crate::model::shipment::Load>,

    /// If the shipment is not completed, this penalty is added to the overall
    /// cost of the routes. A shipment is considered completed if one of its pickup
    /// and delivery alternatives is visited. The cost may be expressed in the
    /// same unit used for all other cost-related fields in the model and must be
    /// positive.
    ///
    /// *IMPORTANT*: If this penalty is not specified, it is considered infinite,
    /// i.e. the shipment must be completed.
    pub penalty_cost: std::option::Option<f64>,

    /// The set of vehicles that may perform this shipment. If empty, all vehicles
    /// may perform it. Vehicles are given by their index in the `ShipmentModel`'s
    /// `vehicles` list.
    pub allowed_vehicle_indices: std::vec::Vec<i32>,

    /// Specifies the cost that is incurred when this shipment is delivered by each
    /// vehicle. If specified, it must have EITHER:
    ///
    /// * the same number of elements as `costs_per_vehicle_indices`.
    ///   `costs_per_vehicle[i]` corresponds to vehicle
    ///   `costs_per_vehicle_indices[i]` of the model.
    /// * the same number of elements as there are vehicles in the model. The
    ///   i-th element corresponds to vehicle #i of the model.
    ///
    /// These costs must be in the same unit as `penalty_cost` and must not be
    /// negative. Leave this field empty, if there are no such costs.
    pub costs_per_vehicle: std::vec::Vec<f64>,

    /// Indices of the vehicles to which `costs_per_vehicle` applies. If non-empty,
    /// it must have the same number of elements as `costs_per_vehicle`. A vehicle
    /// index may not be specified more than once. If a vehicle is excluded from
    /// `costs_per_vehicle_indices`, its cost is zero.
    pub costs_per_vehicle_indices: std::vec::Vec<i32>,

    /// Specifies the maximum relative detour time compared to the shortest path
    /// from pickup to delivery. If specified, it must be nonnegative, and the
    /// shipment must contain at least a pickup and a delivery.
    ///
    /// For example, let t be the shortest time taken to go from the selected
    /// pickup alternative directly to the selected delivery alternative. Then
    /// setting `pickup_to_delivery_relative_detour_limit` enforces:
    ///
    /// ```norust
    /// start_time(delivery) - start_time(pickup) <=
    /// std::ceil(t * (1.0 + pickup_to_delivery_relative_detour_limit))
    /// ```
    ///
    /// If both relative and absolute limits are specified on the same shipment,
    /// the more constraining limit is used for each possible pickup/delivery pair.
    /// As of 2017/10, detours are only supported when travel durations do not
    /// depend on vehicles.
    pub pickup_to_delivery_relative_detour_limit: std::option::Option<f64>,

    /// Specifies the maximum absolute detour time compared to the shortest path
    /// from pickup to delivery. If specified, it must be nonnegative, and the
    /// shipment must contain at least a pickup and a delivery.
    ///
    /// For example, let t be the shortest time taken to go from the selected
    /// pickup alternative directly to the selected delivery alternative. Then
    /// setting `pickup_to_delivery_absolute_detour_limit` enforces:
    ///
    /// ```norust
    /// start_time(delivery) - start_time(pickup) <=
    /// t + pickup_to_delivery_absolute_detour_limit
    /// ```
    ///
    /// If both relative and absolute limits are specified on the same shipment,
    /// the more constraining limit is used for each possible pickup/delivery pair.
    /// As of 2017/10, detours are only supported when travel durations do not
    /// depend on vehicles.
    pub pickup_to_delivery_absolute_detour_limit: std::option::Option<wkt::Duration>,

    /// Specifies the maximum duration from start of pickup to start of delivery of
    /// a shipment. If specified, it must be nonnegative, and the shipment must
    /// contain at least a pickup and a delivery. This does not depend on which
    /// alternatives are selected for pickup and delivery, nor on vehicle speed.
    /// This can be specified alongside maximum detour constraints: the solution
    /// will respect both specifications.
    pub pickup_to_delivery_time_limit: std::option::Option<wkt::Duration>,

    /// Non-empty string specifying a "type" for this shipment.
    /// This feature can be used to define incompatibilities or requirements
    /// between `shipment_types` (see `shipment_type_incompatibilities` and
    /// `shipment_type_requirements` in `ShipmentModel`).
    ///
    /// Differs from `visit_types` which is specified for a single visit: All
    /// pickup/deliveries belonging to the same shipment share the same
    /// `shipment_type`.
    pub shipment_type: std::string::String,

    /// Specifies a label for this shipment. This label is reported in the response
    /// in the `shipment_label` of the corresponding
    /// [ShipmentRoute.Visit][google.cloud.optimization.v1.ShipmentRoute.Visit].
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute.Visit]: crate::model::shipment_route::Visit
    pub label: std::string::String,

    /// If true, skip this shipment, but don't apply a `penalty_cost`.
    ///
    /// Ignoring a shipment results in a validation error when there are any
    /// `shipment_type_requirements` in the model.
    ///
    /// Ignoring a shipment that is performed in `injected_first_solution_routes`
    /// or `injected_solution_constraint` is permitted; the solver removes the
    /// related pickup/delivery visits from the performing route.
    /// `precedence_rules` that reference ignored shipments will also be ignored.
    pub ignore: bool,

    /// Deprecated: Use
    /// [Shipment.load_demands][google.cloud.optimization.v1.Shipment.load_demands]
    /// instead.
    ///
    /// [google.cloud.optimization.v1.Shipment.load_demands]: crate::model::Shipment::load_demands
    #[deprecated]
    pub demands: std::vec::Vec<crate::model::CapacityQuantity>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Shipment {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [pickups][crate::model::Shipment::pickups].
    pub fn set_pickups<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::shipment::VisitRequest>,
    {
        use std::iter::Iterator;
        self.pickups = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [deliveries][crate::model::Shipment::deliveries].
    pub fn set_deliveries<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::shipment::VisitRequest>,
    {
        use std::iter::Iterator;
        self.deliveries = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [load_demands][crate::model::Shipment::load_demands].
    pub fn set_load_demands<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::shipment::Load>,
    {
        use std::iter::Iterator;
        self.load_demands = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [penalty_cost][crate::model::Shipment::penalty_cost].
    pub fn set_penalty_cost<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.penalty_cost = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [penalty_cost][crate::model::Shipment::penalty_cost].
    pub fn set_or_clear_penalty_cost<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.penalty_cost = v.map(|x| x.into());
        self
    }

    /// Sets the value of [allowed_vehicle_indices][crate::model::Shipment::allowed_vehicle_indices].
    pub fn set_allowed_vehicle_indices<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<i32>,
    {
        use std::iter::Iterator;
        self.allowed_vehicle_indices = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [costs_per_vehicle][crate::model::Shipment::costs_per_vehicle].
    pub fn set_costs_per_vehicle<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<f64>,
    {
        use std::iter::Iterator;
        self.costs_per_vehicle = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [costs_per_vehicle_indices][crate::model::Shipment::costs_per_vehicle_indices].
    pub fn set_costs_per_vehicle_indices<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<i32>,
    {
        use std::iter::Iterator;
        self.costs_per_vehicle_indices = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [pickup_to_delivery_relative_detour_limit][crate::model::Shipment::pickup_to_delivery_relative_detour_limit].
    pub fn set_pickup_to_delivery_relative_detour_limit<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.pickup_to_delivery_relative_detour_limit = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [pickup_to_delivery_relative_detour_limit][crate::model::Shipment::pickup_to_delivery_relative_detour_limit].
    pub fn set_or_clear_pickup_to_delivery_relative_detour_limit<T>(
        mut self,
        v: std::option::Option<T>,
    ) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.pickup_to_delivery_relative_detour_limit = v.map(|x| x.into());
        self
    }

    /// Sets the value of [pickup_to_delivery_absolute_detour_limit][crate::model::Shipment::pickup_to_delivery_absolute_detour_limit].
    pub fn set_pickup_to_delivery_absolute_detour_limit<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.pickup_to_delivery_absolute_detour_limit = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [pickup_to_delivery_absolute_detour_limit][crate::model::Shipment::pickup_to_delivery_absolute_detour_limit].
    pub fn set_or_clear_pickup_to_delivery_absolute_detour_limit<T>(
        mut self,
        v: std::option::Option<T>,
    ) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.pickup_to_delivery_absolute_detour_limit = v.map(|x| x.into());
        self
    }

    /// Sets the value of [pickup_to_delivery_time_limit][crate::model::Shipment::pickup_to_delivery_time_limit].
    pub fn set_pickup_to_delivery_time_limit<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.pickup_to_delivery_time_limit = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [pickup_to_delivery_time_limit][crate::model::Shipment::pickup_to_delivery_time_limit].
    pub fn set_or_clear_pickup_to_delivery_time_limit<T>(
        mut self,
        v: std::option::Option<T>,
    ) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.pickup_to_delivery_time_limit = v.map(|x| x.into());
        self
    }

    /// Sets the value of [shipment_type][crate::model::Shipment::shipment_type].
    pub fn set_shipment_type<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.shipment_type = v.into();
        self
    }

    /// Sets the value of [label][crate::model::Shipment::label].
    pub fn set_label<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.label = v.into();
        self
    }

    /// Sets the value of [ignore][crate::model::Shipment::ignore].
    pub fn set_ignore<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.ignore = v.into();
        self
    }

    /// Sets the value of [demands][crate::model::Shipment::demands].
    #[deprecated]
    pub fn set_demands<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::CapacityQuantity>,
    {
        use std::iter::Iterator;
        self.demands = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for Shipment {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.Shipment"
    }
}

/// Defines additional types related to [Shipment].
pub mod shipment {
    #[allow(unused_imports)]
    use super::*;

    /// Request for a visit which can be done by a vehicle: it has a geo-location
    /// (or two, see below), opening and closing times represented by time windows,
    /// and a service duration time (time spent by the vehicle once it has arrived
    /// to pickup or drop off goods).
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct VisitRequest {
        /// The geo-location where the vehicle arrives when performing this
        /// `VisitRequest`. If the shipment model has duration distance matrices,
        /// `arrival_location` must not be specified.
        pub arrival_location: std::option::Option<gtype::model::LatLng>,

        /// The waypoint where the vehicle arrives when performing this
        /// `VisitRequest`. If the shipment model has duration distance matrices,
        /// `arrival_waypoint` must not be specified.
        pub arrival_waypoint: std::option::Option<crate::model::Waypoint>,

        /// The geo-location where the vehicle departs after completing this
        /// `VisitRequest`. Can be omitted if it is the same as `arrival_location`.
        /// If the shipment model has duration distance matrices,
        /// `departure_location` must not be specified.
        pub departure_location: std::option::Option<gtype::model::LatLng>,

        /// The waypoint where the vehicle departs after completing this
        /// `VisitRequest`. Can be omitted if it is the same as `arrival_waypoint`.
        /// If the shipment model has duration distance matrices,
        /// `departure_waypoint` must not be specified.
        pub departure_waypoint: std::option::Option<crate::model::Waypoint>,

        /// Specifies tags attached to the visit request.
        /// Empty or duplicate strings are not allowed.
        pub tags: std::vec::Vec<std::string::String>,

        /// Time windows which constrain the arrival time at a visit.
        /// Note that a vehicle may depart outside of the arrival time window, i.e.
        /// arrival time + duration do not need to be inside a time window. This can
        /// result in waiting time if the vehicle arrives before
        /// [TimeWindow.start_time][google.cloud.optimization.v1.TimeWindow.start_time].
        ///
        /// The absence of `TimeWindow` means that the vehicle can perform this visit
        /// at any time.
        ///
        /// Time windows must be disjoint, i.e. no time window must overlap with or
        /// be adjacent to another, and they must be in increasing order.
        ///
        /// `cost_per_hour_after_soft_end_time` and `soft_end_time` can only
        /// be set if there is a single time window.
        ///
        /// [google.cloud.optimization.v1.TimeWindow.start_time]: crate::model::TimeWindow::start_time
        pub time_windows: std::vec::Vec<crate::model::TimeWindow>,

        /// Duration of the visit, i.e. time spent by the vehicle between arrival
        /// and departure (to be added to the possible waiting time; see
        /// `time_windows`).
        pub duration: std::option::Option<wkt::Duration>,

        /// Cost to service this visit request on a vehicle route. This can be used
        /// to pay different costs for each alternative pickup or delivery of a
        /// shipment. This cost must be in the same unit as `Shipment.penalty_cost`
        /// and must not be negative.
        pub cost: f64,

        /// Load demands of this visit request. This is just like
        /// [Shipment.load_demands][google.cloud.optimization.v1.Shipment.load_demands]
        /// field, except that it only applies to this
        /// [VisitRequest][google.cloud.optimization.v1.Shipment.VisitRequest]
        /// instead of the whole [Shipment][google.cloud.optimization.v1.Shipment].
        /// The demands listed here are added to the demands listed in
        /// [Shipment.load_demands][google.cloud.optimization.v1.Shipment.load_demands].
        ///
        /// [google.cloud.optimization.v1.Shipment]: crate::model::Shipment
        /// [google.cloud.optimization.v1.Shipment.VisitRequest]: crate::model::shipment::VisitRequest
        /// [google.cloud.optimization.v1.Shipment.load_demands]: crate::model::Shipment::load_demands
        pub load_demands:
            std::collections::HashMap<std::string::String, crate::model::shipment::Load>,

        /// Specifies the types of the visit. This may be used to allocate additional
        /// time required for a vehicle to complete this visit (see
        /// [Vehicle.extra_visit_duration_for_visit_type][google.cloud.optimization.v1.Vehicle.extra_visit_duration_for_visit_type]).
        ///
        /// A type can only appear once.
        ///
        /// [google.cloud.optimization.v1.Vehicle.extra_visit_duration_for_visit_type]: crate::model::Vehicle::extra_visit_duration_for_visit_type
        pub visit_types: std::vec::Vec<std::string::String>,

        /// Specifies a label for this `VisitRequest`. This label is reported in the
        /// response as `visit_label` in the corresponding
        /// [ShipmentRoute.Visit][google.cloud.optimization.v1.ShipmentRoute.Visit].
        ///
        /// [google.cloud.optimization.v1.ShipmentRoute.Visit]: crate::model::shipment_route::Visit
        pub label: std::string::String,

        /// Deprecated: Use
        /// [VisitRequest.load_demands][google.cloud.optimization.v1.Shipment.VisitRequest.load_demands]
        /// instead.
        ///
        /// [google.cloud.optimization.v1.Shipment.VisitRequest.load_demands]: crate::model::shipment::VisitRequest::load_demands
        #[deprecated]
        pub demands: std::vec::Vec<crate::model::CapacityQuantity>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl VisitRequest {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [arrival_location][crate::model::shipment::VisitRequest::arrival_location].
        pub fn set_arrival_location<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<gtype::model::LatLng>,
        {
            self.arrival_location = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [arrival_location][crate::model::shipment::VisitRequest::arrival_location].
        pub fn set_or_clear_arrival_location<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<gtype::model::LatLng>,
        {
            self.arrival_location = v.map(|x| x.into());
            self
        }

        /// Sets the value of [arrival_waypoint][crate::model::shipment::VisitRequest::arrival_waypoint].
        pub fn set_arrival_waypoint<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::Waypoint>,
        {
            self.arrival_waypoint = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [arrival_waypoint][crate::model::shipment::VisitRequest::arrival_waypoint].
        pub fn set_or_clear_arrival_waypoint<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::Waypoint>,
        {
            self.arrival_waypoint = v.map(|x| x.into());
            self
        }

        /// Sets the value of [departure_location][crate::model::shipment::VisitRequest::departure_location].
        pub fn set_departure_location<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<gtype::model::LatLng>,
        {
            self.departure_location = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [departure_location][crate::model::shipment::VisitRequest::departure_location].
        pub fn set_or_clear_departure_location<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<gtype::model::LatLng>,
        {
            self.departure_location = v.map(|x| x.into());
            self
        }

        /// Sets the value of [departure_waypoint][crate::model::shipment::VisitRequest::departure_waypoint].
        pub fn set_departure_waypoint<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::Waypoint>,
        {
            self.departure_waypoint = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [departure_waypoint][crate::model::shipment::VisitRequest::departure_waypoint].
        pub fn set_or_clear_departure_waypoint<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::Waypoint>,
        {
            self.departure_waypoint = v.map(|x| x.into());
            self
        }

        /// Sets the value of [tags][crate::model::shipment::VisitRequest::tags].
        pub fn set_tags<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.tags = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [time_windows][crate::model::shipment::VisitRequest::time_windows].
        pub fn set_time_windows<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::TimeWindow>,
        {
            use std::iter::Iterator;
            self.time_windows = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [duration][crate::model::shipment::VisitRequest::duration].
        pub fn set_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [duration][crate::model::shipment::VisitRequest::duration].
        pub fn set_or_clear_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.duration = v.map(|x| x.into());
            self
        }

        /// Sets the value of [cost][crate::model::shipment::VisitRequest::cost].
        pub fn set_cost<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
            self.cost = v.into();
            self
        }

        /// Sets the value of [load_demands][crate::model::shipment::VisitRequest::load_demands].
        pub fn set_load_demands<T, K, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = (K, V)>,
            K: std::convert::Into<std::string::String>,
            V: std::convert::Into<crate::model::shipment::Load>,
        {
            use std::iter::Iterator;
            self.load_demands = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
            self
        }

        /// Sets the value of [visit_types][crate::model::shipment::VisitRequest::visit_types].
        pub fn set_visit_types<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.visit_types = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [label][crate::model::shipment::VisitRequest::label].
        pub fn set_label<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.label = v.into();
            self
        }

        /// Sets the value of [demands][crate::model::shipment::VisitRequest::demands].
        #[deprecated]
        pub fn set_demands<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::CapacityQuantity>,
        {
            use std::iter::Iterator;
            self.demands = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for VisitRequest {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.Shipment.VisitRequest"
        }
    }

    /// When performing a visit, a predefined amount may be added to the vehicle
    /// load if it's a pickup, or subtracted if it's a delivery. This message
    /// defines such amount. See
    /// [load_demands][google.cloud.optimization.v1.Shipment.load_demands].
    ///
    /// [google.cloud.optimization.v1.Shipment.load_demands]: crate::model::Shipment::load_demands
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct Load {
        /// The amount by which the load of the vehicle performing the corresponding
        /// visit will vary. Since it is an integer, users are advised to choose an
        /// appropriate unit to avoid loss of precision. Must be ≥ 0.
        pub amount: i64,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Load {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [amount][crate::model::shipment::Load::amount].
        pub fn set_amount<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
            self.amount = v.into();
            self
        }
    }

    impl wkt::message::Message for Load {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.Shipment.Load"
        }
    }
}

/// Specifies incompatibilties between shipments depending on their
/// shipment_type. The appearance of incompatible shipments on the same route is
/// restricted based on the incompatibility mode.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ShipmentTypeIncompatibility {
    /// List of incompatible types. Two shipments having different `shipment_types`
    /// among those listed are "incompatible".
    pub types: std::vec::Vec<std::string::String>,

    /// Mode applied to the incompatibility.
    pub incompatibility_mode: crate::model::shipment_type_incompatibility::IncompatibilityMode,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ShipmentTypeIncompatibility {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [types][crate::model::ShipmentTypeIncompatibility::types].
    pub fn set_types<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.types = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [incompatibility_mode][crate::model::ShipmentTypeIncompatibility::incompatibility_mode].
    pub fn set_incompatibility_mode<
        T: std::convert::Into<crate::model::shipment_type_incompatibility::IncompatibilityMode>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.incompatibility_mode = v.into();
        self
    }
}

impl wkt::message::Message for ShipmentTypeIncompatibility {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.ShipmentTypeIncompatibility"
    }
}

/// Defines additional types related to [ShipmentTypeIncompatibility].
pub mod shipment_type_incompatibility {
    #[allow(unused_imports)]
    use super::*;

    /// Modes defining how the appearance of incompatible shipments are restricted
    /// on the same route.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum IncompatibilityMode {
        /// Unspecified incompatibility mode. This value should never be used.
        Unspecified,
        /// In this mode, two shipments with incompatible types can never share the
        /// same vehicle.
        NotPerformedBySameVehicle,
        /// For two shipments with incompatible types with the
        /// `NOT_IN_SAME_VEHICLE_SIMULTANEOUSLY` incompatibility mode:
        ///
        /// * If both are pickups only (no deliveries) or deliveries only (no
        ///   pickups), they cannot share the same vehicle at all.
        /// * If one of the shipments has a delivery and the other a pickup, the two
        ///   shipments can share the same vehicle iff the former shipment is
        ///   delivered before the latter is picked up.
        NotInSameVehicleSimultaneously,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [IncompatibilityMode::value] or
        /// [IncompatibilityMode::name].
        UnknownValue(incompatibility_mode::UnknownValue),
    }

    #[doc(hidden)]
    pub mod incompatibility_mode {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl IncompatibilityMode {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::NotPerformedBySameVehicle => std::option::Option::Some(1),
                Self::NotInSameVehicleSimultaneously => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("INCOMPATIBILITY_MODE_UNSPECIFIED"),
                Self::NotPerformedBySameVehicle => {
                    std::option::Option::Some("NOT_PERFORMED_BY_SAME_VEHICLE")
                }
                Self::NotInSameVehicleSimultaneously => {
                    std::option::Option::Some("NOT_IN_SAME_VEHICLE_SIMULTANEOUSLY")
                }
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for IncompatibilityMode {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for IncompatibilityMode {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for IncompatibilityMode {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::NotPerformedBySameVehicle,
                2 => Self::NotInSameVehicleSimultaneously,
                _ => Self::UnknownValue(incompatibility_mode::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for IncompatibilityMode {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "INCOMPATIBILITY_MODE_UNSPECIFIED" => Self::Unspecified,
                "NOT_PERFORMED_BY_SAME_VEHICLE" => Self::NotPerformedBySameVehicle,
                "NOT_IN_SAME_VEHICLE_SIMULTANEOUSLY" => Self::NotInSameVehicleSimultaneously,
                _ => Self::UnknownValue(incompatibility_mode::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for IncompatibilityMode {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::NotPerformedBySameVehicle => serializer.serialize_i32(1),
                Self::NotInSameVehicleSimultaneously => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for IncompatibilityMode {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<IncompatibilityMode>::new(
                ".google.cloud.optimization.v1.ShipmentTypeIncompatibility.IncompatibilityMode",
            ))
        }
    }
}

/// Specifies requirements between shipments based on their shipment_type.
/// The specifics of the requirement are defined by the requirement mode.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ShipmentTypeRequirement {
    /// List of alternative shipment types required by the
    /// `dependent_shipment_types`.
    pub required_shipment_type_alternatives: std::vec::Vec<std::string::String>,

    /// All shipments with a type in the `dependent_shipment_types` field require
    /// at least one shipment of type `required_shipment_type_alternatives` to be
    /// visited on the same route.
    ///
    /// NOTE: Chains of requirements such that a `shipment_type` depends on itself
    /// are not allowed.
    pub dependent_shipment_types: std::vec::Vec<std::string::String>,

    /// Mode applied to the requirement.
    pub requirement_mode: crate::model::shipment_type_requirement::RequirementMode,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ShipmentTypeRequirement {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [required_shipment_type_alternatives][crate::model::ShipmentTypeRequirement::required_shipment_type_alternatives].
    pub fn set_required_shipment_type_alternatives<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.required_shipment_type_alternatives = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [dependent_shipment_types][crate::model::ShipmentTypeRequirement::dependent_shipment_types].
    pub fn set_dependent_shipment_types<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.dependent_shipment_types = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [requirement_mode][crate::model::ShipmentTypeRequirement::requirement_mode].
    pub fn set_requirement_mode<
        T: std::convert::Into<crate::model::shipment_type_requirement::RequirementMode>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.requirement_mode = v.into();
        self
    }
}

impl wkt::message::Message for ShipmentTypeRequirement {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.ShipmentTypeRequirement"
    }
}

/// Defines additional types related to [ShipmentTypeRequirement].
pub mod shipment_type_requirement {
    #[allow(unused_imports)]
    use super::*;

    /// Modes defining the appearance of dependent shipments on a route.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum RequirementMode {
        /// Unspecified requirement mode. This value should never be used.
        Unspecified,
        /// In this mode, all "dependent" shipments must share the same vehicle as at
        /// least one of their "required" shipments.
        PerformedBySameVehicle,
        /// With the `IN_SAME_VEHICLE_AT_PICKUP_TIME` mode, all "dependent"
        /// shipments need to have at least one "required" shipment on their vehicle
        /// at the time of their pickup.
        ///
        /// A "dependent" shipment pickup must therefore have either:
        ///
        /// * A delivery-only "required" shipment delivered on the route after, or
        /// * A "required" shipment picked up on the route before it, and if the
        ///   "required" shipment has a delivery, this delivery must be performed
        ///   after the "dependent" shipment's pickup.
        InSameVehicleAtPickupTime,
        /// Same as before, except the "dependent" shipments need to have a
        /// "required" shipment on their vehicle at the time of their *delivery*.
        InSameVehicleAtDeliveryTime,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [RequirementMode::value] or
        /// [RequirementMode::name].
        UnknownValue(requirement_mode::UnknownValue),
    }

    #[doc(hidden)]
    pub mod requirement_mode {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl RequirementMode {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::PerformedBySameVehicle => std::option::Option::Some(1),
                Self::InSameVehicleAtPickupTime => std::option::Option::Some(2),
                Self::InSameVehicleAtDeliveryTime => std::option::Option::Some(3),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("REQUIREMENT_MODE_UNSPECIFIED"),
                Self::PerformedBySameVehicle => {
                    std::option::Option::Some("PERFORMED_BY_SAME_VEHICLE")
                }
                Self::InSameVehicleAtPickupTime => {
                    std::option::Option::Some("IN_SAME_VEHICLE_AT_PICKUP_TIME")
                }
                Self::InSameVehicleAtDeliveryTime => {
                    std::option::Option::Some("IN_SAME_VEHICLE_AT_DELIVERY_TIME")
                }
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for RequirementMode {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for RequirementMode {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for RequirementMode {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::PerformedBySameVehicle,
                2 => Self::InSameVehicleAtPickupTime,
                3 => Self::InSameVehicleAtDeliveryTime,
                _ => Self::UnknownValue(requirement_mode::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for RequirementMode {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "REQUIREMENT_MODE_UNSPECIFIED" => Self::Unspecified,
                "PERFORMED_BY_SAME_VEHICLE" => Self::PerformedBySameVehicle,
                "IN_SAME_VEHICLE_AT_PICKUP_TIME" => Self::InSameVehicleAtPickupTime,
                "IN_SAME_VEHICLE_AT_DELIVERY_TIME" => Self::InSameVehicleAtDeliveryTime,
                _ => Self::UnknownValue(requirement_mode::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for RequirementMode {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::PerformedBySameVehicle => serializer.serialize_i32(1),
                Self::InSameVehicleAtPickupTime => serializer.serialize_i32(2),
                Self::InSameVehicleAtDeliveryTime => serializer.serialize_i32(3),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for RequirementMode {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<RequirementMode>::new(
                ".google.cloud.optimization.v1.ShipmentTypeRequirement.RequirementMode",
            ))
        }
    }
}

/// Encapsulates a set of optional conditions to satisfy when calculating
/// vehicle routes. This is similar to `RouteModifiers` in the Google Maps
/// Platform API; see:
/// <https://developers.google.com/maps/documentation/routes/reference/rest/v2/RouteModifiers>.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RouteModifiers {
    /// Specifies whether to avoid toll roads where reasonable. Preference will be
    /// given to routes not containing toll roads. Applies only to motorized travel
    /// modes.
    pub avoid_tolls: bool,

    /// Specifies whether to avoid highways where reasonable. Preference will be
    /// given to routes not containing highways. Applies only to motorized travel
    /// modes.
    pub avoid_highways: bool,

    /// Specifies whether to avoid ferries where reasonable. Preference will be
    /// given to routes not containing travel by ferries. Applies only to motorized
    /// travel modes.
    pub avoid_ferries: bool,

    /// Optional. Specifies whether to avoid navigating indoors where reasonable.
    /// Preference will be given to routes not containing indoor navigation.
    /// Applies only to the `WALKING` travel mode.
    pub avoid_indoor: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RouteModifiers {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [avoid_tolls][crate::model::RouteModifiers::avoid_tolls].
    pub fn set_avoid_tolls<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.avoid_tolls = v.into();
        self
    }

    /// Sets the value of [avoid_highways][crate::model::RouteModifiers::avoid_highways].
    pub fn set_avoid_highways<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.avoid_highways = v.into();
        self
    }

    /// Sets the value of [avoid_ferries][crate::model::RouteModifiers::avoid_ferries].
    pub fn set_avoid_ferries<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.avoid_ferries = v.into();
        self
    }

    /// Sets the value of [avoid_indoor][crate::model::RouteModifiers::avoid_indoor].
    pub fn set_avoid_indoor<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.avoid_indoor = v.into();
        self
    }
}

impl wkt::message::Message for RouteModifiers {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.RouteModifiers"
    }
}

/// Models a vehicle in a shipment problem. Solving a shipment problem will
/// build a route starting from `start_location` and ending at `end_location`
/// for this vehicle. A route is a sequence of visits (see `ShipmentRoute`).
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Vehicle {
    /// The travel mode which affects the roads usable by the vehicle and its
    /// speed. See also `travel_duration_multiple`.
    pub travel_mode: crate::model::vehicle::TravelMode,

    /// Optional. A set of conditions to satisfy that affect the way routes are
    /// calculated for the given vehicle.
    pub route_modifiers: std::option::Option<crate::model::RouteModifiers>,

    /// Geographic location where the vehicle starts before picking up any
    /// shipments. If not specified, the vehicle starts at its first pickup.
    /// If the shipment model has duration and distance matrices, `start_location`
    /// must not be specified.
    pub start_location: std::option::Option<gtype::model::LatLng>,

    /// Waypoint representing a geographic location where the vehicle starts before
    /// picking up any shipments. If neither `start_waypoint` nor `start_location`
    /// is specified, the vehicle starts at its first pickup.
    /// If the shipment model has duration and distance matrices, `start_waypoint`
    /// must not be specified.
    pub start_waypoint: std::option::Option<crate::model::Waypoint>,

    /// Geographic location where the vehicle ends after it has completed its last
    /// `VisitRequest`. If not specified the vehicle's `ShipmentRoute` ends
    /// immediately when it completes its last `VisitRequest`.
    /// If the shipment model has duration and distance matrices, `end_location`
    /// must not be specified.
    pub end_location: std::option::Option<gtype::model::LatLng>,

    /// Waypoint representing a geographic location where the vehicle ends after
    /// it has completed its last `VisitRequest`. If neither `end_waypoint` nor
    /// `end_location` is specified, the vehicle's `ShipmentRoute` ends immediately
    /// when it completes its last `VisitRequest`.
    /// If the shipment model has duration and distance matrices, `end_waypoint`
    /// must not be specified.
    pub end_waypoint: std::option::Option<crate::model::Waypoint>,

    /// Specifies tags attached to the start of the vehicle's route.
    ///
    /// Empty or duplicate strings are not allowed.
    pub start_tags: std::vec::Vec<std::string::String>,

    /// Specifies tags attached to the end of the vehicle's route.
    ///
    /// Empty or duplicate strings are not allowed.
    pub end_tags: std::vec::Vec<std::string::String>,

    /// Time windows during which the vehicle may depart its start location.
    /// They must be within the global time limits (see
    /// [ShipmentModel.global_*][google.cloud.optimization.v1.ShipmentModel.global_start_time]
    /// fields). If unspecified, there is no limitation besides those global time
    /// limits.
    ///
    /// Time windows belonging to the same repeated field must be disjoint, i.e. no
    /// time window can overlap with or be adjacent to another, and they must be in
    /// chronological order.
    ///
    /// `cost_per_hour_after_soft_end_time` and `soft_end_time` can only be set if
    /// there is a single time window.
    ///
    /// [google.cloud.optimization.v1.ShipmentModel.global_start_time]: crate::model::ShipmentModel::global_start_time
    pub start_time_windows: std::vec::Vec<crate::model::TimeWindow>,

    /// Time windows during which the vehicle may arrive at its end location.
    /// They must be within the global time limits (see
    /// [ShipmentModel.global_*][google.cloud.optimization.v1.ShipmentModel.global_start_time]
    /// fields). If unspecified, there is no limitation besides those global time
    /// limits.
    ///
    /// Time windows belonging to the same repeated field must be disjoint, i.e. no
    /// time window can overlap with or be adjacent to another, and they must be in
    /// chronological order.
    ///
    /// `cost_per_hour_after_soft_end_time` and `soft_end_time` can only be set if
    /// there is a single time window.
    ///
    /// [google.cloud.optimization.v1.ShipmentModel.global_start_time]: crate::model::ShipmentModel::global_start_time
    pub end_time_windows: std::vec::Vec<crate::model::TimeWindow>,

    /// Specifies a multiplicative factor that can be used to increase or decrease
    /// travel times of this vehicle. For example, setting this to 2.0 means
    /// that this vehicle is slower and has travel times that are twice what they
    /// are for standard vehicles. This multiple does not affect visit durations.
    /// It does affect cost if `cost_per_hour` or `cost_per_traveled_hour` are
    /// specified. This must be in the range [0.001, 1000.0]. If unset, the vehicle
    /// is standard, and this multiple is considered 1.0.
    ///
    /// WARNING: Travel times will be rounded to the nearest second after this
    /// multiple is applied but before performing any numerical operations, thus,
    /// a small multiple may result in a loss of precision.
    ///
    /// See also `extra_visit_duration_for_visit_type` below.
    pub travel_duration_multiple: std::option::Option<f64>,

    /// Unloading policy enforced on the vehicle.
    pub unloading_policy: crate::model::vehicle::UnloadingPolicy,

    /// Capacities of the vehicle (weight, volume, # of pallets for example).
    /// The keys in the map are the identifiers of the type of load, consistent
    /// with the keys of the
    /// [Shipment.load_demands][google.cloud.optimization.v1.Shipment.load_demands]
    /// field. If a given key is absent from this map, the corresponding capacity
    /// is considered to be limitless.
    ///
    /// [google.cloud.optimization.v1.Shipment.load_demands]: crate::model::Shipment::load_demands
    pub load_limits:
        std::collections::HashMap<std::string::String, crate::model::vehicle::LoadLimit>,

    /// Vehicle costs: all costs add up and must be in the same unit as
    /// [Shipment.penalty_cost][google.cloud.optimization.v1.Shipment.penalty_cost].
    ///
    /// Cost per hour of the vehicle route. This cost is applied to the total time
    /// taken by the route, and includes travel time, waiting time, and visit time.
    /// Using `cost_per_hour` instead of just `cost_per_traveled_hour` may result
    /// in additional latency.
    ///
    /// [google.cloud.optimization.v1.Shipment.penalty_cost]: crate::model::Shipment::penalty_cost
    pub cost_per_hour: f64,

    /// Cost per traveled hour of the vehicle route. This cost is applied only to
    /// travel time taken by the route (i.e., that reported in
    /// [ShipmentRoute.transitions][google.cloud.optimization.v1.ShipmentRoute.transitions]),
    /// and excludes waiting time and visit time.
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute.transitions]: crate::model::ShipmentRoute::transitions
    pub cost_per_traveled_hour: f64,

    /// Cost per kilometer of the vehicle route. This cost is applied to the
    /// distance reported in the
    /// [ShipmentRoute.transitions][google.cloud.optimization.v1.ShipmentRoute.transitions]
    /// and does not apply to any distance implicitly traveled from the
    /// `arrival_location` to the `departure_location` of a single `VisitRequest`.
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute.transitions]: crate::model::ShipmentRoute::transitions
    pub cost_per_kilometer: f64,

    /// Fixed cost applied if this vehicle is used to handle a shipment.
    pub fixed_cost: f64,

    /// This field only applies to vehicles when their route does not serve any
    /// shipments. It indicates if the vehicle should be considered as used or not
    /// in this case.
    ///
    /// If true, the vehicle goes from its start to its end location even if it
    /// doesn't serve any shipments, and time and distance costs resulting from its
    /// start --> end travel are taken into account.
    ///
    /// Otherwise, it doesn't travel from its start to its end location, and no
    /// `break_rule` or delay (from `TransitionAttributes`) are scheduled for this
    /// vehicle. In this case, the vehicle's `ShipmentRoute` doesn't contain any
    /// information except for the vehicle index and label.
    pub used_if_route_is_empty: bool,

    /// Limit applied to the total duration of the vehicle's route. In a given
    /// `OptimizeToursResponse`, the route duration of a vehicle is the
    /// difference between its `vehicle_end_time` and `vehicle_start_time`.
    pub route_duration_limit: std::option::Option<crate::model::vehicle::DurationLimit>,

    /// Limit applied to the travel duration of the vehicle's route. In a given
    /// `OptimizeToursResponse`, the route travel duration is the sum of all its
    /// [transitions.travel_duration][google.cloud.optimization.v1.ShipmentRoute.Transition.travel_duration].
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute.Transition.travel_duration]: crate::model::shipment_route::Transition::travel_duration
    pub travel_duration_limit: std::option::Option<crate::model::vehicle::DurationLimit>,

    /// Limit applied to the total distance of the vehicle's route. In a given
    /// `OptimizeToursResponse`, the route distance is the sum of all its
    /// [transitions.travel_distance_meters][google.cloud.optimization.v1.ShipmentRoute.Transition.travel_distance_meters].
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute.Transition.travel_distance_meters]: crate::model::shipment_route::Transition::travel_distance_meters
    pub route_distance_limit: std::option::Option<crate::model::DistanceLimit>,

    /// Specifies a map from visit_types strings to durations. The duration is time
    /// in addition to
    /// [VisitRequest.duration][google.cloud.optimization.v1.Shipment.VisitRequest.duration]
    /// to be taken at visits with the specified `visit_types`. This extra visit
    /// duration adds cost if `cost_per_hour` is specified. Keys (i.e.
    /// `visit_types`) cannot be empty strings.
    ///
    /// If a visit request has multiple types, a duration will be added for each
    /// type in the map.
    ///
    /// [google.cloud.optimization.v1.Shipment.VisitRequest.duration]: crate::model::shipment::VisitRequest::duration
    pub extra_visit_duration_for_visit_type:
        std::collections::HashMap<std::string::String, wkt::Duration>,

    /// Describes the break schedule to be enforced on this vehicle.
    /// If empty, no breaks will be scheduled for this vehicle.
    pub break_rule: std::option::Option<crate::model::BreakRule>,

    /// Specifies a label for this vehicle. This label is reported in the response
    /// as the `vehicle_label` of the corresponding
    /// [ShipmentRoute][google.cloud.optimization.v1.ShipmentRoute].
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute]: crate::model::ShipmentRoute
    pub label: std::string::String,

    /// If true, `used_if_route_is_empty` must be false, and this vehicle will
    /// remain unused.
    ///
    /// If a shipment is performed by an ignored vehicle in
    /// `injected_first_solution_routes`, it is skipped in the first solution but
    /// is free to be performed in the response.
    ///
    /// If a shipment is performed by an ignored vehicle in
    /// `injected_solution_constraint` and any related pickup/delivery is
    /// constrained to remain on the vehicle (i.e., not relaxed to level
    /// `RELAX_ALL_AFTER_THRESHOLD`), it is skipped in the response.
    /// If a shipment has a non-empty `allowed_vehicle_indices` field and all of
    /// the allowed vehicles are ignored, it is skipped in the response.
    pub ignore: bool,

    /// Deprecated: No longer used.
    /// Indices in the `break_rule` field in the source
    /// [ShipmentModel][google.cloud.optimization.v1.ShipmentModel]. They
    /// correspond to break rules enforced on the vehicle.
    ///
    /// As of 2018/03, at most one rule index per vehicle can be specified.
    ///
    /// [google.cloud.optimization.v1.ShipmentModel]: crate::model::ShipmentModel
    #[deprecated]
    pub break_rule_indices: std::vec::Vec<i32>,

    /// Deprecated: Use
    /// [Vehicle.load_limits][google.cloud.optimization.v1.Vehicle.load_limits]
    /// instead.
    ///
    /// [google.cloud.optimization.v1.Vehicle.load_limits]: crate::model::Vehicle::load_limits
    #[deprecated]
    pub capacities: std::vec::Vec<crate::model::CapacityQuantity>,

    /// Deprecated: Use
    /// [Vehicle.LoadLimit.start_load_interval][google.cloud.optimization.v1.Vehicle.LoadLimit.start_load_interval]
    /// instead.
    ///
    /// [google.cloud.optimization.v1.Vehicle.LoadLimit.start_load_interval]: crate::model::vehicle::LoadLimit::start_load_interval
    #[deprecated]
    pub start_load_intervals: std::vec::Vec<crate::model::CapacityQuantityInterval>,

    /// Deprecated: Use
    /// [Vehicle.LoadLimit.end_load_interval][google.cloud.optimization.v1.Vehicle.LoadLimit.end_load_interval]
    /// instead.
    ///
    /// [google.cloud.optimization.v1.Vehicle.LoadLimit.end_load_interval]: crate::model::vehicle::LoadLimit::end_load_interval
    #[deprecated]
    pub end_load_intervals: std::vec::Vec<crate::model::CapacityQuantityInterval>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Vehicle {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [travel_mode][crate::model::Vehicle::travel_mode].
    pub fn set_travel_mode<T: std::convert::Into<crate::model::vehicle::TravelMode>>(
        mut self,
        v: T,
    ) -> Self {
        self.travel_mode = v.into();
        self
    }

    /// Sets the value of [route_modifiers][crate::model::Vehicle::route_modifiers].
    pub fn set_route_modifiers<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::RouteModifiers>,
    {
        self.route_modifiers = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [route_modifiers][crate::model::Vehicle::route_modifiers].
    pub fn set_or_clear_route_modifiers<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::RouteModifiers>,
    {
        self.route_modifiers = v.map(|x| x.into());
        self
    }

    /// Sets the value of [start_location][crate::model::Vehicle::start_location].
    pub fn set_start_location<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<gtype::model::LatLng>,
    {
        self.start_location = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [start_location][crate::model::Vehicle::start_location].
    pub fn set_or_clear_start_location<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<gtype::model::LatLng>,
    {
        self.start_location = v.map(|x| x.into());
        self
    }

    /// Sets the value of [start_waypoint][crate::model::Vehicle::start_waypoint].
    pub fn set_start_waypoint<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Waypoint>,
    {
        self.start_waypoint = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [start_waypoint][crate::model::Vehicle::start_waypoint].
    pub fn set_or_clear_start_waypoint<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Waypoint>,
    {
        self.start_waypoint = v.map(|x| x.into());
        self
    }

    /// Sets the value of [end_location][crate::model::Vehicle::end_location].
    pub fn set_end_location<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<gtype::model::LatLng>,
    {
        self.end_location = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [end_location][crate::model::Vehicle::end_location].
    pub fn set_or_clear_end_location<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<gtype::model::LatLng>,
    {
        self.end_location = v.map(|x| x.into());
        self
    }

    /// Sets the value of [end_waypoint][crate::model::Vehicle::end_waypoint].
    pub fn set_end_waypoint<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Waypoint>,
    {
        self.end_waypoint = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [end_waypoint][crate::model::Vehicle::end_waypoint].
    pub fn set_or_clear_end_waypoint<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Waypoint>,
    {
        self.end_waypoint = v.map(|x| x.into());
        self
    }

    /// Sets the value of [start_tags][crate::model::Vehicle::start_tags].
    pub fn set_start_tags<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.start_tags = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [end_tags][crate::model::Vehicle::end_tags].
    pub fn set_end_tags<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.end_tags = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [start_time_windows][crate::model::Vehicle::start_time_windows].
    pub fn set_start_time_windows<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::TimeWindow>,
    {
        use std::iter::Iterator;
        self.start_time_windows = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [end_time_windows][crate::model::Vehicle::end_time_windows].
    pub fn set_end_time_windows<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::TimeWindow>,
    {
        use std::iter::Iterator;
        self.end_time_windows = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [travel_duration_multiple][crate::model::Vehicle::travel_duration_multiple].
    pub fn set_travel_duration_multiple<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.travel_duration_multiple = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [travel_duration_multiple][crate::model::Vehicle::travel_duration_multiple].
    pub fn set_or_clear_travel_duration_multiple<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.travel_duration_multiple = v.map(|x| x.into());
        self
    }

    /// Sets the value of [unloading_policy][crate::model::Vehicle::unloading_policy].
    pub fn set_unloading_policy<T: std::convert::Into<crate::model::vehicle::UnloadingPolicy>>(
        mut self,
        v: T,
    ) -> Self {
        self.unloading_policy = v.into();
        self
    }

    /// Sets the value of [load_limits][crate::model::Vehicle::load_limits].
    pub fn set_load_limits<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::vehicle::LoadLimit>,
    {
        use std::iter::Iterator;
        self.load_limits = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [cost_per_hour][crate::model::Vehicle::cost_per_hour].
    pub fn set_cost_per_hour<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.cost_per_hour = v.into();
        self
    }

    /// Sets the value of [cost_per_traveled_hour][crate::model::Vehicle::cost_per_traveled_hour].
    pub fn set_cost_per_traveled_hour<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.cost_per_traveled_hour = v.into();
        self
    }

    /// Sets the value of [cost_per_kilometer][crate::model::Vehicle::cost_per_kilometer].
    pub fn set_cost_per_kilometer<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.cost_per_kilometer = v.into();
        self
    }

    /// Sets the value of [fixed_cost][crate::model::Vehicle::fixed_cost].
    pub fn set_fixed_cost<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.fixed_cost = v.into();
        self
    }

    /// Sets the value of [used_if_route_is_empty][crate::model::Vehicle::used_if_route_is_empty].
    pub fn set_used_if_route_is_empty<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.used_if_route_is_empty = v.into();
        self
    }

    /// Sets the value of [route_duration_limit][crate::model::Vehicle::route_duration_limit].
    pub fn set_route_duration_limit<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::vehicle::DurationLimit>,
    {
        self.route_duration_limit = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [route_duration_limit][crate::model::Vehicle::route_duration_limit].
    pub fn set_or_clear_route_duration_limit<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::vehicle::DurationLimit>,
    {
        self.route_duration_limit = v.map(|x| x.into());
        self
    }

    /// Sets the value of [travel_duration_limit][crate::model::Vehicle::travel_duration_limit].
    pub fn set_travel_duration_limit<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::vehicle::DurationLimit>,
    {
        self.travel_duration_limit = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [travel_duration_limit][crate::model::Vehicle::travel_duration_limit].
    pub fn set_or_clear_travel_duration_limit<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::vehicle::DurationLimit>,
    {
        self.travel_duration_limit = v.map(|x| x.into());
        self
    }

    /// Sets the value of [route_distance_limit][crate::model::Vehicle::route_distance_limit].
    pub fn set_route_distance_limit<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::DistanceLimit>,
    {
        self.route_distance_limit = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [route_distance_limit][crate::model::Vehicle::route_distance_limit].
    pub fn set_or_clear_route_distance_limit<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::DistanceLimit>,
    {
        self.route_distance_limit = v.map(|x| x.into());
        self
    }

    /// Sets the value of [extra_visit_duration_for_visit_type][crate::model::Vehicle::extra_visit_duration_for_visit_type].
    pub fn set_extra_visit_duration_for_visit_type<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<wkt::Duration>,
    {
        use std::iter::Iterator;
        self.extra_visit_duration_for_visit_type =
            v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [break_rule][crate::model::Vehicle::break_rule].
    pub fn set_break_rule<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::BreakRule>,
    {
        self.break_rule = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [break_rule][crate::model::Vehicle::break_rule].
    pub fn set_or_clear_break_rule<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::BreakRule>,
    {
        self.break_rule = v.map(|x| x.into());
        self
    }

    /// Sets the value of [label][crate::model::Vehicle::label].
    pub fn set_label<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.label = v.into();
        self
    }

    /// Sets the value of [ignore][crate::model::Vehicle::ignore].
    pub fn set_ignore<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.ignore = v.into();
        self
    }

    /// Sets the value of [break_rule_indices][crate::model::Vehicle::break_rule_indices].
    #[deprecated]
    pub fn set_break_rule_indices<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<i32>,
    {
        use std::iter::Iterator;
        self.break_rule_indices = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [capacities][crate::model::Vehicle::capacities].
    #[deprecated]
    pub fn set_capacities<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::CapacityQuantity>,
    {
        use std::iter::Iterator;
        self.capacities = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [start_load_intervals][crate::model::Vehicle::start_load_intervals].
    #[deprecated]
    pub fn set_start_load_intervals<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::CapacityQuantityInterval>,
    {
        use std::iter::Iterator;
        self.start_load_intervals = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [end_load_intervals][crate::model::Vehicle::end_load_intervals].
    #[deprecated]
    pub fn set_end_load_intervals<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::CapacityQuantityInterval>,
    {
        use std::iter::Iterator;
        self.end_load_intervals = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for Vehicle {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.Vehicle"
    }
}

/// Defines additional types related to [Vehicle].
pub mod vehicle {
    #[allow(unused_imports)]
    use super::*;

    /// Defines a load limit applying to a vehicle, e.g. "this truck may only
    /// carry up to 3500 kg". See
    /// [load_limits][google.cloud.optimization.v1.Vehicle.load_limits].
    ///
    /// [google.cloud.optimization.v1.Vehicle.load_limits]: crate::model::Vehicle::load_limits
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct LoadLimit {
        /// The maximum acceptable amount of load.
        pub max_load: std::option::Option<i64>,

        /// A soft limit of the load. See
        /// [cost_per_unit_above_soft_max][google.cloud.optimization.v1.Vehicle.LoadLimit.cost_per_unit_above_soft_max].
        ///
        /// [google.cloud.optimization.v1.Vehicle.LoadLimit.cost_per_unit_above_soft_max]: crate::model::vehicle::LoadLimit::cost_per_unit_above_soft_max
        pub soft_max_load: i64,

        /// If the load ever exceeds
        /// [soft_max_load][google.cloud.optimization.v1.Vehicle.LoadLimit.soft_max_load]
        /// along this vehicle's route, the following cost penalty applies (only once
        /// per vehicle): (load -
        /// [soft_max_load][google.cloud.optimization.v1.Vehicle.LoadLimit.soft_max_load])
        ///
        /// * [cost_per_unit_above_soft_max][google.cloud.optimization.v1.Vehicle.LoadLimit.cost_per_unit_above_soft_max]. All costs
        ///   add up and must be in the same unit as
        ///   [Shipment.penalty_cost][google.cloud.optimization.v1.Shipment.penalty_cost].
        ///
        /// [google.cloud.optimization.v1.Shipment.penalty_cost]: crate::model::Shipment::penalty_cost
        /// [google.cloud.optimization.v1.Vehicle.LoadLimit.cost_per_unit_above_soft_max]: crate::model::vehicle::LoadLimit::cost_per_unit_above_soft_max
        /// [google.cloud.optimization.v1.Vehicle.LoadLimit.soft_max_load]: crate::model::vehicle::LoadLimit::soft_max_load
        pub cost_per_unit_above_soft_max: f64,

        /// The acceptable load interval of the vehicle at the start of the route.
        pub start_load_interval: std::option::Option<crate::model::vehicle::load_limit::Interval>,

        /// The acceptable load interval of the vehicle at the end of the route.
        pub end_load_interval: std::option::Option<crate::model::vehicle::load_limit::Interval>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl LoadLimit {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [max_load][crate::model::vehicle::LoadLimit::max_load].
        pub fn set_max_load<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<i64>,
        {
            self.max_load = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [max_load][crate::model::vehicle::LoadLimit::max_load].
        pub fn set_or_clear_max_load<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<i64>,
        {
            self.max_load = v.map(|x| x.into());
            self
        }

        /// Sets the value of [soft_max_load][crate::model::vehicle::LoadLimit::soft_max_load].
        pub fn set_soft_max_load<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
            self.soft_max_load = v.into();
            self
        }

        /// Sets the value of [cost_per_unit_above_soft_max][crate::model::vehicle::LoadLimit::cost_per_unit_above_soft_max].
        pub fn set_cost_per_unit_above_soft_max<T: std::convert::Into<f64>>(
            mut self,
            v: T,
        ) -> Self {
            self.cost_per_unit_above_soft_max = v.into();
            self
        }

        /// Sets the value of [start_load_interval][crate::model::vehicle::LoadLimit::start_load_interval].
        pub fn set_start_load_interval<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::vehicle::load_limit::Interval>,
        {
            self.start_load_interval = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [start_load_interval][crate::model::vehicle::LoadLimit::start_load_interval].
        pub fn set_or_clear_start_load_interval<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::vehicle::load_limit::Interval>,
        {
            self.start_load_interval = v.map(|x| x.into());
            self
        }

        /// Sets the value of [end_load_interval][crate::model::vehicle::LoadLimit::end_load_interval].
        pub fn set_end_load_interval<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::vehicle::load_limit::Interval>,
        {
            self.end_load_interval = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [end_load_interval][crate::model::vehicle::LoadLimit::end_load_interval].
        pub fn set_or_clear_end_load_interval<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::vehicle::load_limit::Interval>,
        {
            self.end_load_interval = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for LoadLimit {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.Vehicle.LoadLimit"
        }
    }

    /// Defines additional types related to [LoadLimit].
    pub mod load_limit {
        #[allow(unused_imports)]
        use super::*;

        /// Interval of acceptable load amounts.
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct Interval {
            /// A minimum acceptable load. Must be ≥ 0.
            /// If they're both specified,
            /// [min][google.cloud.optimization.v1.Vehicle.LoadLimit.Interval.min] must
            /// be ≤
            /// [max][google.cloud.optimization.v1.Vehicle.LoadLimit.Interval.max].
            ///
            /// [google.cloud.optimization.v1.Vehicle.LoadLimit.Interval.max]: crate::model::vehicle::load_limit::Interval::max
            /// [google.cloud.optimization.v1.Vehicle.LoadLimit.Interval.min]: crate::model::vehicle::load_limit::Interval::min
            pub min: i64,

            /// A maximum acceptable load. Must be ≥ 0. If unspecified, the maximum
            /// load is unrestricted by this message.
            /// If they're both specified,
            /// [min][google.cloud.optimization.v1.Vehicle.LoadLimit.Interval.min] must
            /// be ≤
            /// [max][google.cloud.optimization.v1.Vehicle.LoadLimit.Interval.max].
            ///
            /// [google.cloud.optimization.v1.Vehicle.LoadLimit.Interval.max]: crate::model::vehicle::load_limit::Interval::max
            /// [google.cloud.optimization.v1.Vehicle.LoadLimit.Interval.min]: crate::model::vehicle::load_limit::Interval::min
            pub max: std::option::Option<i64>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl Interval {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [min][crate::model::vehicle::load_limit::Interval::min].
            pub fn set_min<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
                self.min = v.into();
                self
            }

            /// Sets the value of [max][crate::model::vehicle::load_limit::Interval::max].
            pub fn set_max<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<i64>,
            {
                self.max = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [max][crate::model::vehicle::load_limit::Interval::max].
            pub fn set_or_clear_max<T>(mut self, v: std::option::Option<T>) -> Self
            where
                T: std::convert::Into<i64>,
            {
                self.max = v.map(|x| x.into());
                self
            }
        }

        impl wkt::message::Message for Interval {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.optimization.v1.Vehicle.LoadLimit.Interval"
            }
        }
    }

    /// A limit defining a maximum duration of the route of a vehicle. It can be
    /// either hard or soft.
    ///
    /// When a soft limit field is defined, both the soft max threshold and its
    /// associated cost must be defined together.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct DurationLimit {
        /// A hard limit constraining the duration to be at most max_duration.
        pub max_duration: std::option::Option<wkt::Duration>,

        /// A soft limit not enforcing a maximum duration limit, but when violated
        /// makes the route incur a cost. This cost adds up to other costs defined in
        /// the model, with the same unit.
        ///
        /// If defined, `soft_max_duration` must be nonnegative. If max_duration is
        /// also defined, `soft_max_duration` must be less than max_duration.
        pub soft_max_duration: std::option::Option<wkt::Duration>,

        /// Cost per hour incurred if the `soft_max_duration` threshold is violated.
        /// The additional cost is 0 if the duration is under the threshold,
        /// otherwise the cost depends on the duration as follows:
        ///
        /// ```norust
        ///   cost_per_hour_after_soft_max * (duration - soft_max_duration)
        /// ```
        ///
        /// The cost must be nonnegative.
        pub cost_per_hour_after_soft_max: std::option::Option<f64>,

        /// A soft limit not enforcing a maximum duration limit, but when violated
        /// makes the route incur a cost, quadratic in the duration. This cost adds
        /// up to other costs defined in the model, with the same unit.
        ///
        /// If defined, `quadratic_soft_max_duration` must be nonnegative. If
        /// `max_duration` is also defined, `quadratic_soft_max_duration` must be
        /// less than `max_duration`, and the difference must be no larger than one
        /// day:
        ///
        /// `max_duration - quadratic_soft_max_duration <= 86400 seconds`
        pub quadratic_soft_max_duration: std::option::Option<wkt::Duration>,

        /// Cost per square hour incurred if the
        /// `quadratic_soft_max_duration` threshold is violated.
        ///
        /// The additional cost is 0 if the duration is under the threshold,
        /// otherwise the cost depends on the duration as follows:
        ///
        /// ```norust
        ///   cost_per_square_hour_after_quadratic_soft_max *
        ///   (duration - quadratic_soft_max_duration)^2
        /// ```
        ///
        /// The cost must be nonnegative.
        pub cost_per_square_hour_after_quadratic_soft_max: std::option::Option<f64>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl DurationLimit {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [max_duration][crate::model::vehicle::DurationLimit::max_duration].
        pub fn set_max_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.max_duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [max_duration][crate::model::vehicle::DurationLimit::max_duration].
        pub fn set_or_clear_max_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.max_duration = v.map(|x| x.into());
            self
        }

        /// Sets the value of [soft_max_duration][crate::model::vehicle::DurationLimit::soft_max_duration].
        pub fn set_soft_max_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.soft_max_duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [soft_max_duration][crate::model::vehicle::DurationLimit::soft_max_duration].
        pub fn set_or_clear_soft_max_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.soft_max_duration = v.map(|x| x.into());
            self
        }

        /// Sets the value of [cost_per_hour_after_soft_max][crate::model::vehicle::DurationLimit::cost_per_hour_after_soft_max].
        pub fn set_cost_per_hour_after_soft_max<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<f64>,
        {
            self.cost_per_hour_after_soft_max = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [cost_per_hour_after_soft_max][crate::model::vehicle::DurationLimit::cost_per_hour_after_soft_max].
        pub fn set_or_clear_cost_per_hour_after_soft_max<T>(
            mut self,
            v: std::option::Option<T>,
        ) -> Self
        where
            T: std::convert::Into<f64>,
        {
            self.cost_per_hour_after_soft_max = v.map(|x| x.into());
            self
        }

        /// Sets the value of [quadratic_soft_max_duration][crate::model::vehicle::DurationLimit::quadratic_soft_max_duration].
        pub fn set_quadratic_soft_max_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.quadratic_soft_max_duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [quadratic_soft_max_duration][crate::model::vehicle::DurationLimit::quadratic_soft_max_duration].
        pub fn set_or_clear_quadratic_soft_max_duration<T>(
            mut self,
            v: std::option::Option<T>,
        ) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.quadratic_soft_max_duration = v.map(|x| x.into());
            self
        }

        /// Sets the value of [cost_per_square_hour_after_quadratic_soft_max][crate::model::vehicle::DurationLimit::cost_per_square_hour_after_quadratic_soft_max].
        pub fn set_cost_per_square_hour_after_quadratic_soft_max<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<f64>,
        {
            self.cost_per_square_hour_after_quadratic_soft_max =
                std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [cost_per_square_hour_after_quadratic_soft_max][crate::model::vehicle::DurationLimit::cost_per_square_hour_after_quadratic_soft_max].
        pub fn set_or_clear_cost_per_square_hour_after_quadratic_soft_max<T>(
            mut self,
            v: std::option::Option<T>,
        ) -> Self
        where
            T: std::convert::Into<f64>,
        {
            self.cost_per_square_hour_after_quadratic_soft_max = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for DurationLimit {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.Vehicle.DurationLimit"
        }
    }

    /// Travel modes which can be used by vehicles.
    ///
    /// These should be a subset of the Google Maps Platform Routes Preferred API
    /// travel modes, see:
    /// <https://developers.google.com/maps/documentation/routes_preferred/reference/rest/Shared.Types/RouteTravelMode>.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum TravelMode {
        /// Unspecified travel mode, equivalent to `DRIVING`.
        Unspecified,
        /// Travel mode corresponding to driving directions (car, ...).
        Driving,
        /// Travel mode corresponding to walking directions.
        Walking,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [TravelMode::value] or
        /// [TravelMode::name].
        UnknownValue(travel_mode::UnknownValue),
    }

    #[doc(hidden)]
    pub mod travel_mode {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl TravelMode {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::Driving => std::option::Option::Some(1),
                Self::Walking => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("TRAVEL_MODE_UNSPECIFIED"),
                Self::Driving => std::option::Option::Some("DRIVING"),
                Self::Walking => std::option::Option::Some("WALKING"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for TravelMode {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for TravelMode {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for TravelMode {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::Driving,
                2 => Self::Walking,
                _ => Self::UnknownValue(travel_mode::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for TravelMode {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "TRAVEL_MODE_UNSPECIFIED" => Self::Unspecified,
                "DRIVING" => Self::Driving,
                "WALKING" => Self::Walking,
                _ => Self::UnknownValue(travel_mode::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for TravelMode {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::Driving => serializer.serialize_i32(1),
                Self::Walking => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for TravelMode {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<TravelMode>::new(
                ".google.cloud.optimization.v1.Vehicle.TravelMode",
            ))
        }
    }

    /// Policy on how a vehicle can be unloaded. Applies only to shipments having
    /// both a pickup and a delivery.
    ///
    /// Other shipments are free to occur anywhere on the route independent of
    /// `unloading_policy`.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum UnloadingPolicy {
        /// Unspecified unloading policy; deliveries must just occur after their
        /// corresponding pickups.
        Unspecified,
        /// Deliveries must occur in reverse order of pickups
        LastInFirstOut,
        /// Deliveries must occur in the same order as pickups
        FirstInFirstOut,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [UnloadingPolicy::value] or
        /// [UnloadingPolicy::name].
        UnknownValue(unloading_policy::UnknownValue),
    }

    #[doc(hidden)]
    pub mod unloading_policy {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl UnloadingPolicy {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::LastInFirstOut => std::option::Option::Some(1),
                Self::FirstInFirstOut => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("UNLOADING_POLICY_UNSPECIFIED"),
                Self::LastInFirstOut => std::option::Option::Some("LAST_IN_FIRST_OUT"),
                Self::FirstInFirstOut => std::option::Option::Some("FIRST_IN_FIRST_OUT"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for UnloadingPolicy {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for UnloadingPolicy {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for UnloadingPolicy {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::LastInFirstOut,
                2 => Self::FirstInFirstOut,
                _ => Self::UnknownValue(unloading_policy::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for UnloadingPolicy {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "UNLOADING_POLICY_UNSPECIFIED" => Self::Unspecified,
                "LAST_IN_FIRST_OUT" => Self::LastInFirstOut,
                "FIRST_IN_FIRST_OUT" => Self::FirstInFirstOut,
                _ => Self::UnknownValue(unloading_policy::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for UnloadingPolicy {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::LastInFirstOut => serializer.serialize_i32(1),
                Self::FirstInFirstOut => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for UnloadingPolicy {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<UnloadingPolicy>::new(
                ".google.cloud.optimization.v1.Vehicle.UnloadingPolicy",
            ))
        }
    }
}

/// Time windows constrain the time of an event, such as the arrival time at a
/// visit, or the start and end time of a vehicle.
///
/// Hard time window bounds, `start_time` and `end_time`, enforce the earliest
/// and latest time of the event, such that `start_time <= event_time <=
/// end_time`. The soft time window lower bound, `soft_start_time`, expresses a
/// preference for the event to happen at or after `soft_start_time` by incurring
/// a cost proportional to how long before soft_start_time the event occurs. The
/// soft time window upper bound, `soft_end_time`, expresses a preference for the
/// event to happen at or before `soft_end_time` by incurring a cost proportional
/// to how long after `soft_end_time` the event occurs. `start_time`, `end_time`,
/// `soft_start_time` and `soft_end_time` should be within the global time limits
/// (see
/// [ShipmentModel.global_start_time][google.cloud.optimization.v1.ShipmentModel.global_start_time]
/// and
/// [ShipmentModel.global_end_time][google.cloud.optimization.v1.ShipmentModel.global_end_time])
/// and should respect:
///
/// ```norust
///   0 <= `start_time` <= `soft_start_time` <= `end_time` and
///   0 <= `start_time` <= `soft_end_time` <= `end_time`.
/// ```
///
/// [google.cloud.optimization.v1.ShipmentModel.global_end_time]: crate::model::ShipmentModel::global_end_time
/// [google.cloud.optimization.v1.ShipmentModel.global_start_time]: crate::model::ShipmentModel::global_start_time
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct TimeWindow {
    /// The hard time window start time. If unspecified it will be set to
    /// `ShipmentModel.global_start_time`.
    pub start_time: std::option::Option<wkt::Timestamp>,

    /// The hard time window end time. If unspecified it will be set to
    /// `ShipmentModel.global_end_time`.
    pub end_time: std::option::Option<wkt::Timestamp>,

    /// The soft start time of the time window.
    pub soft_start_time: std::option::Option<wkt::Timestamp>,

    /// The soft end time of the time window.
    pub soft_end_time: std::option::Option<wkt::Timestamp>,

    /// A cost per hour added to other costs in the model if the event occurs
    /// before soft_start_time, computed as:
    ///
    /// ```norust
    ///    max(0, soft_start_time - t.seconds)
    ///                           * cost_per_hour_before_soft_start_time / 3600,
    /// t being the time of the event.
    /// ```
    ///
    /// This cost must be positive, and the field can only be set if
    /// soft_start_time has been set.
    pub cost_per_hour_before_soft_start_time: std::option::Option<f64>,

    /// A cost per hour added to other costs in the model if the event occurs after
    /// `soft_end_time`, computed as:
    ///
    /// ```norust
    ///    max(0, t.seconds - soft_end_time.seconds)
    ///                     * cost_per_hour_after_soft_end_time / 3600,
    /// t being the time of the event.
    /// ```
    ///
    /// This cost must be positive, and the field can only be set if
    /// `soft_end_time` has been set.
    pub cost_per_hour_after_soft_end_time: std::option::Option<f64>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl TimeWindow {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [start_time][crate::model::TimeWindow::start_time].
    pub fn set_start_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.start_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [start_time][crate::model::TimeWindow::start_time].
    pub fn set_or_clear_start_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.start_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [end_time][crate::model::TimeWindow::end_time].
    pub fn set_end_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.end_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [end_time][crate::model::TimeWindow::end_time].
    pub fn set_or_clear_end_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.end_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [soft_start_time][crate::model::TimeWindow::soft_start_time].
    pub fn set_soft_start_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.soft_start_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [soft_start_time][crate::model::TimeWindow::soft_start_time].
    pub fn set_or_clear_soft_start_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.soft_start_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [soft_end_time][crate::model::TimeWindow::soft_end_time].
    pub fn set_soft_end_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.soft_end_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [soft_end_time][crate::model::TimeWindow::soft_end_time].
    pub fn set_or_clear_soft_end_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.soft_end_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [cost_per_hour_before_soft_start_time][crate::model::TimeWindow::cost_per_hour_before_soft_start_time].
    pub fn set_cost_per_hour_before_soft_start_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.cost_per_hour_before_soft_start_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [cost_per_hour_before_soft_start_time][crate::model::TimeWindow::cost_per_hour_before_soft_start_time].
    pub fn set_or_clear_cost_per_hour_before_soft_start_time<T>(
        mut self,
        v: std::option::Option<T>,
    ) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.cost_per_hour_before_soft_start_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [cost_per_hour_after_soft_end_time][crate::model::TimeWindow::cost_per_hour_after_soft_end_time].
    pub fn set_cost_per_hour_after_soft_end_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.cost_per_hour_after_soft_end_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [cost_per_hour_after_soft_end_time][crate::model::TimeWindow::cost_per_hour_after_soft_end_time].
    pub fn set_or_clear_cost_per_hour_after_soft_end_time<T>(
        mut self,
        v: std::option::Option<T>,
    ) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.cost_per_hour_after_soft_end_time = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for TimeWindow {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.TimeWindow"
    }
}

/// Deprecated: Use
/// [Vehicle.LoadLimit.Interval][google.cloud.optimization.v1.Vehicle.LoadLimit.Interval]
/// instead.
///
/// [google.cloud.optimization.v1.Vehicle.LoadLimit.Interval]: crate::model::vehicle::load_limit::Interval
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
#[deprecated]
pub struct CapacityQuantity {
    pub r#type: std::string::String,

    pub value: i64,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CapacityQuantity {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [r#type][crate::model::CapacityQuantity::type].
    pub fn set_type<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.r#type = v.into();
        self
    }

    /// Sets the value of [value][crate::model::CapacityQuantity::value].
    pub fn set_value<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.value = v.into();
        self
    }
}

impl wkt::message::Message for CapacityQuantity {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.CapacityQuantity"
    }
}

/// Deprecated: Use
/// [Vehicle.LoadLimit.Interval][google.cloud.optimization.v1.Vehicle.LoadLimit.Interval]
/// instead.
///
/// [google.cloud.optimization.v1.Vehicle.LoadLimit.Interval]: crate::model::vehicle::load_limit::Interval
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
#[deprecated]
pub struct CapacityQuantityInterval {
    pub r#type: std::string::String,

    pub min_value: std::option::Option<i64>,

    pub max_value: std::option::Option<i64>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CapacityQuantityInterval {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [r#type][crate::model::CapacityQuantityInterval::type].
    pub fn set_type<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.r#type = v.into();
        self
    }

    /// Sets the value of [min_value][crate::model::CapacityQuantityInterval::min_value].
    pub fn set_min_value<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<i64>,
    {
        self.min_value = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [min_value][crate::model::CapacityQuantityInterval::min_value].
    pub fn set_or_clear_min_value<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<i64>,
    {
        self.min_value = v.map(|x| x.into());
        self
    }

    /// Sets the value of [max_value][crate::model::CapacityQuantityInterval::max_value].
    pub fn set_max_value<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<i64>,
    {
        self.max_value = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [max_value][crate::model::CapacityQuantityInterval::max_value].
    pub fn set_or_clear_max_value<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<i64>,
    {
        self.max_value = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for CapacityQuantityInterval {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.CapacityQuantityInterval"
    }
}

/// A limit defining a maximum distance which can be traveled. It can be either
/// hard or soft.
///
/// If a soft limit is defined, both `soft_max_meters` and
/// `cost_per_kilometer_above_soft_max` must be defined and be nonnegative.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct DistanceLimit {
    /// A hard limit constraining the distance to be at most max_meters. The limit
    /// must be nonnegative.
    pub max_meters: std::option::Option<i64>,

    /// A soft limit not enforcing a maximum distance limit, but when violated
    /// results in a cost which adds up to other costs defined in the model,
    /// with the same unit.
    ///
    /// If defined soft_max_meters must be less than max_meters and must be
    /// nonnegative.
    pub soft_max_meters: std::option::Option<i64>,

    /// Cost per kilometer incurred, increasing up to `soft_max_meters`, with
    /// formula:
    ///
    /// ```norust
    ///   min(distance_meters, soft_max_meters) / 1000.0 *
    ///   cost_per_kilometer_below_soft_max.
    /// ```
    ///
    /// This cost is not supported in `route_distance_limit`.
    pub cost_per_kilometer_below_soft_max: std::option::Option<f64>,

    /// Cost per kilometer incurred if distance is above `soft_max_meters` limit.
    /// The additional cost is 0 if the distance is under the limit, otherwise the
    /// formula used to compute the cost is the following:
    ///
    /// ```norust
    ///   (distance_meters - soft_max_meters) / 1000.0 *
    ///   cost_per_kilometer_above_soft_max.
    /// ```
    ///
    /// The cost must be nonnegative.
    pub cost_per_kilometer_above_soft_max: std::option::Option<f64>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl DistanceLimit {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [max_meters][crate::model::DistanceLimit::max_meters].
    pub fn set_max_meters<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<i64>,
    {
        self.max_meters = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [max_meters][crate::model::DistanceLimit::max_meters].
    pub fn set_or_clear_max_meters<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<i64>,
    {
        self.max_meters = v.map(|x| x.into());
        self
    }

    /// Sets the value of [soft_max_meters][crate::model::DistanceLimit::soft_max_meters].
    pub fn set_soft_max_meters<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<i64>,
    {
        self.soft_max_meters = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [soft_max_meters][crate::model::DistanceLimit::soft_max_meters].
    pub fn set_or_clear_soft_max_meters<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<i64>,
    {
        self.soft_max_meters = v.map(|x| x.into());
        self
    }

    /// Sets the value of [cost_per_kilometer_below_soft_max][crate::model::DistanceLimit::cost_per_kilometer_below_soft_max].
    pub fn set_cost_per_kilometer_below_soft_max<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.cost_per_kilometer_below_soft_max = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [cost_per_kilometer_below_soft_max][crate::model::DistanceLimit::cost_per_kilometer_below_soft_max].
    pub fn set_or_clear_cost_per_kilometer_below_soft_max<T>(
        mut self,
        v: std::option::Option<T>,
    ) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.cost_per_kilometer_below_soft_max = v.map(|x| x.into());
        self
    }

    /// Sets the value of [cost_per_kilometer_above_soft_max][crate::model::DistanceLimit::cost_per_kilometer_above_soft_max].
    pub fn set_cost_per_kilometer_above_soft_max<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.cost_per_kilometer_above_soft_max = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [cost_per_kilometer_above_soft_max][crate::model::DistanceLimit::cost_per_kilometer_above_soft_max].
    pub fn set_or_clear_cost_per_kilometer_above_soft_max<T>(
        mut self,
        v: std::option::Option<T>,
    ) -> Self
    where
        T: std::convert::Into<f64>,
    {
        self.cost_per_kilometer_above_soft_max = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for DistanceLimit {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.DistanceLimit"
    }
}

/// Specifies attributes of transitions between two consecutive visits on a
/// route. Several `TransitionAttributes` may apply to the same transition: in
/// that case, all extra costs add up and the strictest constraint or limit
/// applies (following natural "AND" semantics).
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct TransitionAttributes {
    /// Tags defining the set of (src->dst) transitions these attributes apply to.
    ///
    /// A source visit or vehicle start matches iff its
    /// [VisitRequest.tags][google.cloud.optimization.v1.Shipment.VisitRequest.tags]
    /// or [Vehicle.start_tags][google.cloud.optimization.v1.Vehicle.start_tags]
    /// either contains `src_tag` or does not contain `excluded_src_tag` (depending
    /// on which of these two fields is non-empty).
    ///
    /// [google.cloud.optimization.v1.Shipment.VisitRequest.tags]: crate::model::shipment::VisitRequest::tags
    /// [google.cloud.optimization.v1.Vehicle.start_tags]: crate::model::Vehicle::start_tags
    pub src_tag: std::string::String,

    /// See `src_tag`. Exactly one of `src_tag` and `excluded_src_tag` must be
    /// non-empty.
    pub excluded_src_tag: std::string::String,

    /// A destination visit or vehicle end matches iff its
    /// [VisitRequest.tags][google.cloud.optimization.v1.Shipment.VisitRequest.tags]
    /// or [Vehicle.end_tags][google.cloud.optimization.v1.Vehicle.end_tags] either
    /// contains `dst_tag` or does not contain `excluded_dst_tag` (depending on
    /// which of these two fields is non-empty).
    ///
    /// [google.cloud.optimization.v1.Shipment.VisitRequest.tags]: crate::model::shipment::VisitRequest::tags
    /// [google.cloud.optimization.v1.Vehicle.end_tags]: crate::model::Vehicle::end_tags
    pub dst_tag: std::string::String,

    /// See `dst_tag`. Exactly one of `dst_tag` and `excluded_dst_tag` must be
    /// non-empty.
    pub excluded_dst_tag: std::string::String,

    /// Specifies a cost for performing this transition. This is in the same unit
    /// as all other costs in the model and must not be negative. It is applied on
    /// top of all other existing costs.
    pub cost: f64,

    /// Specifies a cost per kilometer applied to the distance traveled while
    /// performing this transition. It adds up to any
    /// [Vehicle.cost_per_kilometer][google.cloud.optimization.v1.Vehicle.cost_per_kilometer]
    /// specified on vehicles.
    ///
    /// [google.cloud.optimization.v1.Vehicle.cost_per_kilometer]: crate::model::Vehicle::cost_per_kilometer
    pub cost_per_kilometer: f64,

    /// Specifies a limit on the distance traveled while performing this
    /// transition.
    ///
    /// As of 2021/06, only soft limits are supported.
    pub distance_limit: std::option::Option<crate::model::DistanceLimit>,

    /// Specifies a delay incurred when performing this transition.
    ///
    /// This delay always occurs *after* finishing the source visit and *before*
    /// starting the destination visit.
    pub delay: std::option::Option<wkt::Duration>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl TransitionAttributes {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [src_tag][crate::model::TransitionAttributes::src_tag].
    pub fn set_src_tag<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.src_tag = v.into();
        self
    }

    /// Sets the value of [excluded_src_tag][crate::model::TransitionAttributes::excluded_src_tag].
    pub fn set_excluded_src_tag<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.excluded_src_tag = v.into();
        self
    }

    /// Sets the value of [dst_tag][crate::model::TransitionAttributes::dst_tag].
    pub fn set_dst_tag<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.dst_tag = v.into();
        self
    }

    /// Sets the value of [excluded_dst_tag][crate::model::TransitionAttributes::excluded_dst_tag].
    pub fn set_excluded_dst_tag<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.excluded_dst_tag = v.into();
        self
    }

    /// Sets the value of [cost][crate::model::TransitionAttributes::cost].
    pub fn set_cost<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.cost = v.into();
        self
    }

    /// Sets the value of [cost_per_kilometer][crate::model::TransitionAttributes::cost_per_kilometer].
    pub fn set_cost_per_kilometer<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.cost_per_kilometer = v.into();
        self
    }

    /// Sets the value of [distance_limit][crate::model::TransitionAttributes::distance_limit].
    pub fn set_distance_limit<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::DistanceLimit>,
    {
        self.distance_limit = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [distance_limit][crate::model::TransitionAttributes::distance_limit].
    pub fn set_or_clear_distance_limit<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::DistanceLimit>,
    {
        self.distance_limit = v.map(|x| x.into());
        self
    }

    /// Sets the value of [delay][crate::model::TransitionAttributes::delay].
    pub fn set_delay<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.delay = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [delay][crate::model::TransitionAttributes::delay].
    pub fn set_or_clear_delay<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.delay = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for TransitionAttributes {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.TransitionAttributes"
    }
}

/// Encapsulates a waypoint. Waypoints mark arrival and departure locations of
/// VisitRequests, and start and end locations of Vehicles.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Waypoint {
    /// Indicates that the location of this waypoint is meant to have a preference
    /// for the vehicle to stop at a particular side of road. When you set this
    /// value, the route will pass through the location so that the vehicle can
    /// stop at the side of road that the location is biased towards from the
    /// center of the road. This option works only for the 'DRIVING' travel mode,
    /// and when the 'location_type' is set to 'location'.
    pub side_of_road: bool,

    /// Different ways to represent a location.
    pub location_type: std::option::Option<crate::model::waypoint::LocationType>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Waypoint {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [side_of_road][crate::model::Waypoint::side_of_road].
    pub fn set_side_of_road<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.side_of_road = v.into();
        self
    }

    /// Sets the value of [location_type][crate::model::Waypoint::location_type].
    ///
    /// Note that all the setters affecting `location_type` are mutually
    /// exclusive.
    pub fn set_location_type<
        T: std::convert::Into<std::option::Option<crate::model::waypoint::LocationType>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.location_type = v.into();
        self
    }

    /// The value of [location_type][crate::model::Waypoint::location_type]
    /// if it holds a `Location`, `None` if the field is not set or
    /// holds a different branch.
    pub fn location(&self) -> std::option::Option<&std::boxed::Box<crate::model::Location>> {
        #[allow(unreachable_patterns)]
        self.location_type.as_ref().and_then(|v| match v {
            crate::model::waypoint::LocationType::Location(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [location_type][crate::model::Waypoint::location_type]
    /// to hold a `Location`.
    ///
    /// Note that all the setters affecting `location_type` are
    /// mutually exclusive.
    pub fn set_location<T: std::convert::Into<std::boxed::Box<crate::model::Location>>>(
        mut self,
        v: T,
    ) -> Self {
        self.location_type =
            std::option::Option::Some(crate::model::waypoint::LocationType::Location(v.into()));
        self
    }

    /// The value of [location_type][crate::model::Waypoint::location_type]
    /// if it holds a `PlaceId`, `None` if the field is not set or
    /// holds a different branch.
    pub fn place_id(&self) -> std::option::Option<&std::string::String> {
        #[allow(unreachable_patterns)]
        self.location_type.as_ref().and_then(|v| match v {
            crate::model::waypoint::LocationType::PlaceId(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [location_type][crate::model::Waypoint::location_type]
    /// to hold a `PlaceId`.
    ///
    /// Note that all the setters affecting `location_type` are
    /// mutually exclusive.
    pub fn set_place_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.location_type =
            std::option::Option::Some(crate::model::waypoint::LocationType::PlaceId(v.into()));
        self
    }
}

impl wkt::message::Message for Waypoint {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.Waypoint"
    }
}

/// Defines additional types related to [Waypoint].
pub mod waypoint {
    #[allow(unused_imports)]
    use super::*;

    /// Different ways to represent a location.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum LocationType {
        /// A point specified using geographic coordinates, including an optional
        /// heading.
        Location(std::boxed::Box<crate::model::Location>),
        /// The POI Place ID associated with the waypoint.
        PlaceId(std::string::String),
    }
}

/// Encapsulates a location (a geographic point, and an optional heading).
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Location {
    /// The waypoint's geographic coordinates.
    pub lat_lng: std::option::Option<gtype::model::LatLng>,

    /// The compass heading associated with the direction of the flow of traffic.
    /// This value is used to specify the side of the road to use for pickup and
    /// drop-off. Heading values can be from 0 to 360, where 0 specifies a heading
    /// of due North, 90 specifies a heading of due East, etc.
    pub heading: std::option::Option<i32>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Location {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [lat_lng][crate::model::Location::lat_lng].
    pub fn set_lat_lng<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<gtype::model::LatLng>,
    {
        self.lat_lng = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [lat_lng][crate::model::Location::lat_lng].
    pub fn set_or_clear_lat_lng<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<gtype::model::LatLng>,
    {
        self.lat_lng = v.map(|x| x.into());
        self
    }

    /// Sets the value of [heading][crate::model::Location::heading].
    pub fn set_heading<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<i32>,
    {
        self.heading = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [heading][crate::model::Location::heading].
    pub fn set_or_clear_heading<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<i32>,
    {
        self.heading = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for Location {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.Location"
    }
}

/// Rules to generate time breaks for a vehicle (e.g. lunch breaks). A break
/// is a contiguous period of time during which the vehicle remains idle at its
/// current position and cannot perform any visit. A break may occur:
///
/// * during the travel between two visits (which includes the time right
///   before or right after a visit, but not in the middle of a visit), in
///   which case it extends the corresponding transit time between the visits,
/// * or before the vehicle start (the vehicle may not start in the middle of
///   a break), in which case it does not affect the vehicle start time.
/// * or after the vehicle end (ditto, with the vehicle end time).
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BreakRule {
    /// Sequence of breaks. See the `BreakRequest` message.
    pub break_requests: std::vec::Vec<crate::model::break_rule::BreakRequest>,

    /// Several `FrequencyConstraint` may apply. They must all be satisfied by
    /// the `BreakRequest`s of this `BreakRule`. See `FrequencyConstraint`.
    pub frequency_constraints: std::vec::Vec<crate::model::break_rule::FrequencyConstraint>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BreakRule {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [break_requests][crate::model::BreakRule::break_requests].
    pub fn set_break_requests<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::break_rule::BreakRequest>,
    {
        use std::iter::Iterator;
        self.break_requests = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [frequency_constraints][crate::model::BreakRule::frequency_constraints].
    pub fn set_frequency_constraints<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::break_rule::FrequencyConstraint>,
    {
        use std::iter::Iterator;
        self.frequency_constraints = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for BreakRule {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.BreakRule"
    }
}

/// Defines additional types related to [BreakRule].
pub mod break_rule {
    #[allow(unused_imports)]
    use super::*;

    /// The sequence of breaks (i.e. their number and order) that apply to each
    /// vehicle must be known beforehand. The repeated `BreakRequest`s define
    /// that sequence, in the order in which they must occur. Their time windows
    /// (`earliest_start_time` / `latest_start_time`) may overlap, but they must
    /// be compatible with the order (this is checked).
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct BreakRequest {
        /// Required. Lower bound (inclusive) on the start of the break.
        pub earliest_start_time: std::option::Option<wkt::Timestamp>,

        /// Required. Upper bound (inclusive) on the start of the break.
        pub latest_start_time: std::option::Option<wkt::Timestamp>,

        /// Required. Minimum duration of the break. Must be positive.
        pub min_duration: std::option::Option<wkt::Duration>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl BreakRequest {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [earliest_start_time][crate::model::break_rule::BreakRequest::earliest_start_time].
        pub fn set_earliest_start_time<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.earliest_start_time = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [earliest_start_time][crate::model::break_rule::BreakRequest::earliest_start_time].
        pub fn set_or_clear_earliest_start_time<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.earliest_start_time = v.map(|x| x.into());
            self
        }

        /// Sets the value of [latest_start_time][crate::model::break_rule::BreakRequest::latest_start_time].
        pub fn set_latest_start_time<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.latest_start_time = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [latest_start_time][crate::model::break_rule::BreakRequest::latest_start_time].
        pub fn set_or_clear_latest_start_time<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.latest_start_time = v.map(|x| x.into());
            self
        }

        /// Sets the value of [min_duration][crate::model::break_rule::BreakRequest::min_duration].
        pub fn set_min_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.min_duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [min_duration][crate::model::break_rule::BreakRequest::min_duration].
        pub fn set_or_clear_min_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.min_duration = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for BreakRequest {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.BreakRule.BreakRequest"
        }
    }

    /// One may further constrain the frequency and duration of the breaks
    /// specified above, by enforcing a minimum break frequency, such as
    /// "There must be a break of at least 1 hour every 12 hours". Assuming that
    /// this can be interpreted as "Within any sliding time window of 12h, there
    /// must be at least one break of at least one hour", that example would
    /// translate to the following `FrequencyConstraint`:
    ///
    /// ```norust
    /// {
    ///    min_break_duration { seconds: 3600 }         # 1 hour.
    ///    max_inter_break_duration { seconds: 39600 }  # 11 hours (12 - 1 = 11).
    /// }
    /// ```
    ///
    /// The timing and duration of the breaks in the solution will respect all
    /// such constraints, in addition to the time windows and minimum durations
    /// already specified in the `BreakRequest`.
    ///
    /// A `FrequencyConstraint` may in practice apply to non-consecutive breaks.
    /// For example, the following schedule honors the "1h every 12h" example:
    ///
    /// ```norust
    ///   04:00 vehicle start
    ///    .. performing travel and visits ..
    ///   09:00 1 hour break
    ///   10:00 end of the break
    ///    .. performing travel and visits ..
    ///   12:00 20-min lunch break
    ///   12:20 end of the break
    ///    .. performing travel and visits ..
    ///   21:00 1 hour break
    ///   22:00 end of the break
    ///    .. performing travel and visits ..
    ///   23:59 vehicle end
    /// ```
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct FrequencyConstraint {
        /// Required. Minimum break duration for this constraint. Nonnegative.
        /// See description of `FrequencyConstraint`.
        pub min_break_duration: std::option::Option<wkt::Duration>,

        /// Required. Maximum allowed span of any interval of time in the route that
        /// does not include at least partially a break of `duration >=
        /// min_break_duration`. Must be positive.
        pub max_inter_break_duration: std::option::Option<wkt::Duration>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl FrequencyConstraint {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [min_break_duration][crate::model::break_rule::FrequencyConstraint::min_break_duration].
        pub fn set_min_break_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.min_break_duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [min_break_duration][crate::model::break_rule::FrequencyConstraint::min_break_duration].
        pub fn set_or_clear_min_break_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.min_break_duration = v.map(|x| x.into());
            self
        }

        /// Sets the value of [max_inter_break_duration][crate::model::break_rule::FrequencyConstraint::max_inter_break_duration].
        pub fn set_max_inter_break_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.max_inter_break_duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [max_inter_break_duration][crate::model::break_rule::FrequencyConstraint::max_inter_break_duration].
        pub fn set_or_clear_max_inter_break_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.max_inter_break_duration = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for FrequencyConstraint {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.BreakRule.FrequencyConstraint"
        }
    }
}

/// A vehicle's route can be decomposed, along the time axis, like this (we
/// assume there are n visits):
///
/// ```norust
///   |            |            |          |       |  T[2], |        |      |
///   | Transition |  Visit #0  |          |       |  V[2], |        |      |
///   |     #0     |    aka     |   T[1]   |  V[1] |  ...   | V[n-1] | T[n] |
///   |  aka T[0]  |    V[0]    |          |       | V[n-2],|        |      |
///   |            |            |          |       | T[n-1] |        |      |
///   ^            ^            ^          ^       ^        ^        ^      ^
/// vehicle    V[0].start   V[0].end     V[1].   V[1].    V[n].    V[n]. vehicle
///  start     (arrival)   (departure)   start   end      start    end     end
/// ```
///
/// Note that we make a difference between:
///
/// * "punctual events", such as the vehicle start and end and each visit's start
///   and end (aka arrival and departure). They happen at a given second.
/// * "time intervals", such as the visits themselves, and the transition between
///   visits. Though time intervals can sometimes have zero duration, i.e. start
///   and end at the same second, they often have a positive duration.
///
/// Invariants:
///
/// * If there are n visits, there are n+1 transitions.
/// * A visit is always surrounded by a transition before it (same index) and a
///   transition after it (index + 1).
/// * The vehicle start is always followed by transition #0.
/// * The vehicle end is always preceded by transition #n.
///
/// Zooming in, here is what happens during a `Transition` and a `Visit`:
///
/// ```norust
/// ---+-------------------------------------+-----------------------------+-->
///    |           TRANSITION[i]             |           VISIT[i]          |
///    |                                     |                             |
///    |  * TRAVEL: the vehicle moves from   |      PERFORM the visit:     |
///    |    VISIT[i-1].departure_location to |                             |
///    |    VISIT[i].arrival_location, which |  * Spend some time:         |
///    |    takes a given travel duration    |    the "visit duration".    |
///    |    and distance                     |                             |
///    |                                     |  * Load or unload           |
///    |  * BREAKS: the driver may have      |    some quantities from the |
///    |    breaks (e.g. lunch break).       |    vehicle: the "demand".   |
///    |                                     |                             |
///    |  * WAIT: the driver/vehicle does    |                             |
///    |    nothing. This can happen for     |                             |
///    |    many reasons, for example when   |                             |
///    |    the vehicle reaches the next     |                             |
///    |    event's destination before the   |                             |
///    |    start of its time window         |                             |
///    |                                     |                             |
///    |  * DELAY: *right before* the next   |                             |
///    |    arrival. E.g. the vehicle and/or |                             |
///    |    driver spends time unloading.    |                             |
///    |                                     |                             |
/// ---+-------------------------------------+-----------------------------+-->
///    ^                                     ^                             ^
/// V[i-1].end                           V[i].start                    V[i].end
/// ```
///
/// Lastly, here is how the TRAVEL, BREAKS, DELAY and WAIT can be arranged
/// during a transition.
///
/// * They don't overlap.
/// * The DELAY is unique and *must* be a contiguous period of time right
///   before the next visit (or vehicle end). Thus, it suffice to know the
///   delay duration to know its start and end time.
/// * The BREAKS are contiguous, non-overlapping periods of time. The
///   response specifies the start time and duration of each break.
/// * TRAVEL and WAIT are "preemptable": they can be interrupted several times
///   during this transition. Clients can assume that travel happens "as soon as
///   possible" and that "wait" fills the remaining time.
///
/// A (complex) example:
///
/// ```norust
///                                TRANSITION[i]
/// --++-----+-----------------------------------------------------------++-->
///   ||     |       |           |       |           |         |         ||
///   ||  T  |   B   |     T     |       |     B     |         |    D    ||
///   ||  r  |   r   |     r     |   W   |     r     |    W    |    e    ||
///   ||  a  |   e   |     a     |   a   |     e     |    a    |    l    ||
///   ||  v  |   a   |     v     |   i   |     a     |    i    |    a    ||
///   ||  e  |   k   |     e     |   t   |     k     |    t    |    y    ||
///   ||  l  |       |     l     |       |           |         |         ||
///   ||     |       |           |       |           |         |         ||
/// --++-----------------------------------------------------------------++-->
/// ```
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ShipmentRoute {
    /// Vehicle performing the route, identified by its index in the source
    /// `ShipmentModel`.
    pub vehicle_index: i32,

    /// Label of the vehicle performing this route, equal to
    /// `ShipmentModel.vehicles(vehicle_index).label`, if specified.
    pub vehicle_label: std::string::String,

    /// Time at which the vehicle starts its route.
    pub vehicle_start_time: std::option::Option<wkt::Timestamp>,

    /// Time at which the vehicle finishes its route.
    pub vehicle_end_time: std::option::Option<wkt::Timestamp>,

    /// Ordered sequence of visits representing a route.
    /// visits[i] is the i-th visit in the route.
    /// If this field is empty, the vehicle is considered as unused.
    pub visits: std::vec::Vec<crate::model::shipment_route::Visit>,

    /// Ordered list of transitions for the route.
    pub transitions: std::vec::Vec<crate::model::shipment_route::Transition>,

    /// When
    /// [OptimizeToursRequest.consider_road_traffic][google.cloud.optimization.v1.OptimizeToursRequest.consider_road_traffic],
    /// is set to true, this field indicates that inconsistencies in route timings
    /// are predicted using traffic-based travel duration estimates. There may be
    /// insufficient time to complete traffic-adjusted travel, delays, and breaks
    /// between visits, before the first visit, or after the last visit, while
    /// still satisfying the visit and vehicle time windows. For example,
    ///
    /// ```norust
    ///   start_time(previous_visit) + duration(previous_visit) +
    ///   travel_duration(previous_visit, next_visit) > start_time(next_visit)
    /// ```
    ///
    /// Arrival at next_visit will likely happen later than its current
    /// time window due the increased estimate of travel time
    /// `travel_duration(previous_visit, next_visit)` due to traffic. Also, a break
    /// may be forced to overlap with a visit due to an increase in travel time
    /// estimates and visit or break time window restrictions.
    ///
    /// [google.cloud.optimization.v1.OptimizeToursRequest.consider_road_traffic]: crate::model::OptimizeToursRequest::consider_road_traffic
    pub has_traffic_infeasibilities: bool,

    /// The encoded polyline representation of the route.
    /// This field is only populated if
    /// [OptimizeToursRequest.populate_polylines][google.cloud.optimization.v1.OptimizeToursRequest.populate_polylines]
    /// is set to true.
    ///
    /// [google.cloud.optimization.v1.OptimizeToursRequest.populate_polylines]: crate::model::OptimizeToursRequest::populate_polylines
    pub route_polyline: std::option::Option<crate::model::shipment_route::EncodedPolyline>,

    /// Breaks scheduled for the vehicle performing this route.
    /// The `breaks` sequence represents time intervals, each starting at the
    /// corresponding `start_time` and lasting `duration` seconds.
    pub breaks: std::vec::Vec<crate::model::shipment_route::Break>,

    /// Duration, distance and load metrics for this route. The fields of
    /// [AggregatedMetrics][google.cloud.optimization.v1.AggregatedMetrics] are
    /// summed over all
    /// [ShipmentRoute.transitions][google.cloud.optimization.v1.ShipmentRoute.transitions]
    /// or
    /// [ShipmentRoute.visits][google.cloud.optimization.v1.ShipmentRoute.visits],
    /// depending on the context.
    ///
    /// [google.cloud.optimization.v1.AggregatedMetrics]: crate::model::AggregatedMetrics
    /// [google.cloud.optimization.v1.ShipmentRoute.transitions]: crate::model::ShipmentRoute::transitions
    /// [google.cloud.optimization.v1.ShipmentRoute.visits]: crate::model::ShipmentRoute::visits
    pub metrics: std::option::Option<crate::model::AggregatedMetrics>,

    /// Cost of the route, broken down by cost-related request fields.
    /// The keys are proto paths, relative to the input OptimizeToursRequest, e.g.
    /// "model.shipments.pickups.cost", and the values are the total cost
    /// generated by the corresponding cost field, aggregated over the whole route.
    /// In other words, costs["model.shipments.pickups.cost"] is the sum of all
    /// pickup costs over the route. All costs defined in the model are reported in
    /// detail here with the exception of costs related to TransitionAttributes
    /// that are only reported in an aggregated way as of 2022/01.
    pub route_costs: std::collections::HashMap<std::string::String, f64>,

    /// Total cost of the route. The sum of all costs in the cost map.
    pub route_total_cost: f64,

    /// Deprecated: Use
    /// [Transition.vehicle_loads][google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads]
    /// instead. Vehicle loads upon arrival at its end location, for each type
    /// specified in
    /// [Vehicle.capacities][google.cloud.optimization.v1.Vehicle.capacities],
    /// `start_load_intervals`, `end_load_intervals` or demands. Exception: we omit
    /// loads for quantity types unconstrained by intervals and that don't have any
    /// non-zero demand on the route.
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads]: crate::model::shipment_route::Transition::vehicle_loads
    /// [google.cloud.optimization.v1.Vehicle.capacities]: crate::model::Vehicle::capacities
    #[deprecated]
    pub end_loads: std::vec::Vec<crate::model::CapacityQuantity>,

    /// Deprecated: Use
    /// [ShipmentRoute.transitions][google.cloud.optimization.v1.ShipmentRoute.transitions]
    /// instead. Ordered list of travel steps for the route.
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute.transitions]: crate::model::ShipmentRoute::transitions
    #[deprecated]
    pub travel_steps: std::vec::Vec<crate::model::shipment_route::TravelStep>,

    /// Deprecated: No longer used.
    /// This field will only be populated at the
    /// [ShipmentRoute.Visit][google.cloud.optimization.v1.ShipmentRoute.Visit]
    /// level.
    ///
    /// This field is the extra detour time due to the shipments visited on the
    /// route.
    ///
    /// It is equal to `vehicle_end_time` - `vehicle_start_time` - travel duration
    /// from the vehicle's start_location to its `end_location`.
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute.Visit]: crate::model::shipment_route::Visit
    #[deprecated]
    pub vehicle_detour: std::option::Option<wkt::Duration>,

    /// Deprecated: Delay occurring before the vehicle end. See
    /// [TransitionAttributes.delay][google.cloud.optimization.v1.TransitionAttributes.delay].
    ///
    /// [google.cloud.optimization.v1.TransitionAttributes.delay]: crate::model::TransitionAttributes::delay
    #[deprecated]
    pub delay_before_vehicle_end: std::option::Option<crate::model::shipment_route::Delay>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ShipmentRoute {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [vehicle_index][crate::model::ShipmentRoute::vehicle_index].
    pub fn set_vehicle_index<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.vehicle_index = v.into();
        self
    }

    /// Sets the value of [vehicle_label][crate::model::ShipmentRoute::vehicle_label].
    pub fn set_vehicle_label<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.vehicle_label = v.into();
        self
    }

    /// Sets the value of [vehicle_start_time][crate::model::ShipmentRoute::vehicle_start_time].
    pub fn set_vehicle_start_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.vehicle_start_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [vehicle_start_time][crate::model::ShipmentRoute::vehicle_start_time].
    pub fn set_or_clear_vehicle_start_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.vehicle_start_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [vehicle_end_time][crate::model::ShipmentRoute::vehicle_end_time].
    pub fn set_vehicle_end_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.vehicle_end_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [vehicle_end_time][crate::model::ShipmentRoute::vehicle_end_time].
    pub fn set_or_clear_vehicle_end_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.vehicle_end_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [visits][crate::model::ShipmentRoute::visits].
    pub fn set_visits<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::shipment_route::Visit>,
    {
        use std::iter::Iterator;
        self.visits = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [transitions][crate::model::ShipmentRoute::transitions].
    pub fn set_transitions<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::shipment_route::Transition>,
    {
        use std::iter::Iterator;
        self.transitions = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [has_traffic_infeasibilities][crate::model::ShipmentRoute::has_traffic_infeasibilities].
    pub fn set_has_traffic_infeasibilities<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.has_traffic_infeasibilities = v.into();
        self
    }

    /// Sets the value of [route_polyline][crate::model::ShipmentRoute::route_polyline].
    pub fn set_route_polyline<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::shipment_route::EncodedPolyline>,
    {
        self.route_polyline = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [route_polyline][crate::model::ShipmentRoute::route_polyline].
    pub fn set_or_clear_route_polyline<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::shipment_route::EncodedPolyline>,
    {
        self.route_polyline = v.map(|x| x.into());
        self
    }

    /// Sets the value of [breaks][crate::model::ShipmentRoute::breaks].
    pub fn set_breaks<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::shipment_route::Break>,
    {
        use std::iter::Iterator;
        self.breaks = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [metrics][crate::model::ShipmentRoute::metrics].
    pub fn set_metrics<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::AggregatedMetrics>,
    {
        self.metrics = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [metrics][crate::model::ShipmentRoute::metrics].
    pub fn set_or_clear_metrics<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::AggregatedMetrics>,
    {
        self.metrics = v.map(|x| x.into());
        self
    }

    /// Sets the value of [route_costs][crate::model::ShipmentRoute::route_costs].
    pub fn set_route_costs<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<f64>,
    {
        use std::iter::Iterator;
        self.route_costs = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [route_total_cost][crate::model::ShipmentRoute::route_total_cost].
    pub fn set_route_total_cost<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.route_total_cost = v.into();
        self
    }

    /// Sets the value of [end_loads][crate::model::ShipmentRoute::end_loads].
    #[deprecated]
    pub fn set_end_loads<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::CapacityQuantity>,
    {
        use std::iter::Iterator;
        self.end_loads = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [travel_steps][crate::model::ShipmentRoute::travel_steps].
    #[deprecated]
    pub fn set_travel_steps<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::shipment_route::TravelStep>,
    {
        use std::iter::Iterator;
        self.travel_steps = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [vehicle_detour][crate::model::ShipmentRoute::vehicle_detour].
    #[deprecated]
    pub fn set_vehicle_detour<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.vehicle_detour = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [vehicle_detour][crate::model::ShipmentRoute::vehicle_detour].
    #[deprecated]
    pub fn set_or_clear_vehicle_detour<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.vehicle_detour = v.map(|x| x.into());
        self
    }

    /// Sets the value of [delay_before_vehicle_end][crate::model::ShipmentRoute::delay_before_vehicle_end].
    #[deprecated]
    pub fn set_delay_before_vehicle_end<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::shipment_route::Delay>,
    {
        self.delay_before_vehicle_end = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [delay_before_vehicle_end][crate::model::ShipmentRoute::delay_before_vehicle_end].
    #[deprecated]
    pub fn set_or_clear_delay_before_vehicle_end<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::shipment_route::Delay>,
    {
        self.delay_before_vehicle_end = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for ShipmentRoute {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.ShipmentRoute"
    }
}

/// Defines additional types related to [ShipmentRoute].
pub mod shipment_route {
    #[allow(unused_imports)]
    use super::*;

    /// Deprecated: Use
    /// [ShipmentRoute.Transition.delay_duration][google.cloud.optimization.v1.ShipmentRoute.Transition.delay_duration]
    /// instead. Time interval spent on the route resulting from a
    /// [TransitionAttributes.delay][google.cloud.optimization.v1.TransitionAttributes.delay].
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute.Transition.delay_duration]: crate::model::shipment_route::Transition::delay_duration
    /// [google.cloud.optimization.v1.TransitionAttributes.delay]: crate::model::TransitionAttributes::delay
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    #[deprecated]
    pub struct Delay {
        /// Start of the delay.
        pub start_time: std::option::Option<wkt::Timestamp>,

        /// Duration of the delay.
        pub duration: std::option::Option<wkt::Duration>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Delay {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [start_time][crate::model::shipment_route::Delay::start_time].
        pub fn set_start_time<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.start_time = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [start_time][crate::model::shipment_route::Delay::start_time].
        pub fn set_or_clear_start_time<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.start_time = v.map(|x| x.into());
            self
        }

        /// Sets the value of [duration][crate::model::shipment_route::Delay::duration].
        pub fn set_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [duration][crate::model::shipment_route::Delay::duration].
        pub fn set_or_clear_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.duration = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for Delay {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.ShipmentRoute.Delay"
        }
    }

    /// A visit performed during a route. This visit corresponds to a pickup or a
    /// delivery of a `Shipment`.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct Visit {
        /// Index of the `shipments` field in the source
        /// [ShipmentModel][google.cloud.optimization.v1.ShipmentModel].
        ///
        /// [google.cloud.optimization.v1.ShipmentModel]: crate::model::ShipmentModel
        pub shipment_index: i32,

        /// If true the visit corresponds to a pickup of a `Shipment`. Otherwise, it
        /// corresponds to a delivery.
        pub is_pickup: bool,

        /// Index of `VisitRequest` in either the pickup or delivery field of the
        /// `Shipment` (see `is_pickup`).
        pub visit_request_index: i32,

        /// Time at which the visit starts. Note that the vehicle may arrive earlier
        /// than this at the visit location. Times are consistent with the
        /// `ShipmentModel`.
        pub start_time: std::option::Option<wkt::Timestamp>,

        /// Total visit load demand as the sum of the shipment and the visit request
        /// `load_demands`. The values are negative if the visit is a delivery.
        /// Demands are reported for the same types as the
        /// [Transition.loads][google.cloud.optimization.v1.ShipmentRoute.Transition]
        /// (see this field).
        ///
        /// [google.cloud.optimization.v1.ShipmentRoute.Transition]: crate::model::shipment_route::Transition
        pub load_demands:
            std::collections::HashMap<std::string::String, crate::model::shipment::Load>,

        /// Extra detour time due to the shipments visited on the route before the
        /// visit and to the potential waiting time induced by time windows.
        /// If the visit is a delivery, the detour is computed from the corresponding
        /// pickup visit and is equal to:
        ///
        /// ```norust
        /// start_time(delivery) - start_time(pickup)
        /// - (duration(pickup) + travel duration from the pickup location
        /// to the delivery location).
        /// ```
        ///
        /// Otherwise, it is computed from the vehicle `start_location` and is equal
        /// to:
        ///
        /// ```norust
        /// start_time - vehicle_start_time - travel duration from
        /// the vehicle's `start_location` to the visit.
        /// ```
        pub detour: std::option::Option<wkt::Duration>,

        /// Copy of the corresponding `Shipment.label`, if specified in the
        /// `Shipment`.
        pub shipment_label: std::string::String,

        /// Copy of the corresponding
        /// [VisitRequest.label][google.cloud.optimization.v1.Shipment.VisitRequest.label],
        /// if specified in the `VisitRequest`.
        ///
        /// [google.cloud.optimization.v1.Shipment.VisitRequest.label]: crate::model::shipment::VisitRequest::label
        pub visit_label: std::string::String,

        /// Deprecated: Use
        /// [Transition.vehicle_loads][google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads]
        /// instead. Vehicle loads upon arrival at the visit location, for each type
        /// specified in
        /// [Vehicle.capacities][google.cloud.optimization.v1.Vehicle.capacities],
        /// `start_load_intervals`, `end_load_intervals` or `demands`.
        ///
        /// Exception: we omit loads for quantity types unconstrained by intervals
        /// and that don't have any non-zero demand on the route.
        ///
        /// [google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads]: crate::model::shipment_route::Transition::vehicle_loads
        /// [google.cloud.optimization.v1.Vehicle.capacities]: crate::model::Vehicle::capacities
        #[deprecated]
        pub arrival_loads: std::vec::Vec<crate::model::CapacityQuantity>,

        /// Deprecated: Use
        /// [ShipmentRoute.Transition.delay_duration][google.cloud.optimization.v1.ShipmentRoute.Transition.delay_duration]
        /// instead. Delay occurring before the visit starts.
        ///
        /// [google.cloud.optimization.v1.ShipmentRoute.Transition.delay_duration]: crate::model::shipment_route::Transition::delay_duration
        #[deprecated]
        pub delay_before_start: std::option::Option<crate::model::shipment_route::Delay>,

        /// Deprecated: Use
        /// [Visit.load_demands][google.cloud.optimization.v1.ShipmentRoute.Visit.load_demands]
        /// instead.
        ///
        /// [google.cloud.optimization.v1.ShipmentRoute.Visit.load_demands]: crate::model::shipment_route::Visit::load_demands
        #[deprecated]
        pub demands: std::vec::Vec<crate::model::CapacityQuantity>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Visit {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [shipment_index][crate::model::shipment_route::Visit::shipment_index].
        pub fn set_shipment_index<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
            self.shipment_index = v.into();
            self
        }

        /// Sets the value of [is_pickup][crate::model::shipment_route::Visit::is_pickup].
        pub fn set_is_pickup<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
            self.is_pickup = v.into();
            self
        }

        /// Sets the value of [visit_request_index][crate::model::shipment_route::Visit::visit_request_index].
        pub fn set_visit_request_index<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
            self.visit_request_index = v.into();
            self
        }

        /// Sets the value of [start_time][crate::model::shipment_route::Visit::start_time].
        pub fn set_start_time<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.start_time = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [start_time][crate::model::shipment_route::Visit::start_time].
        pub fn set_or_clear_start_time<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.start_time = v.map(|x| x.into());
            self
        }

        /// Sets the value of [load_demands][crate::model::shipment_route::Visit::load_demands].
        pub fn set_load_demands<T, K, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = (K, V)>,
            K: std::convert::Into<std::string::String>,
            V: std::convert::Into<crate::model::shipment::Load>,
        {
            use std::iter::Iterator;
            self.load_demands = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
            self
        }

        /// Sets the value of [detour][crate::model::shipment_route::Visit::detour].
        pub fn set_detour<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.detour = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [detour][crate::model::shipment_route::Visit::detour].
        pub fn set_or_clear_detour<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.detour = v.map(|x| x.into());
            self
        }

        /// Sets the value of [shipment_label][crate::model::shipment_route::Visit::shipment_label].
        pub fn set_shipment_label<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.shipment_label = v.into();
            self
        }

        /// Sets the value of [visit_label][crate::model::shipment_route::Visit::visit_label].
        pub fn set_visit_label<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.visit_label = v.into();
            self
        }

        /// Sets the value of [arrival_loads][crate::model::shipment_route::Visit::arrival_loads].
        #[deprecated]
        pub fn set_arrival_loads<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::CapacityQuantity>,
        {
            use std::iter::Iterator;
            self.arrival_loads = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [delay_before_start][crate::model::shipment_route::Visit::delay_before_start].
        #[deprecated]
        pub fn set_delay_before_start<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::shipment_route::Delay>,
        {
            self.delay_before_start = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [delay_before_start][crate::model::shipment_route::Visit::delay_before_start].
        #[deprecated]
        pub fn set_or_clear_delay_before_start<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::shipment_route::Delay>,
        {
            self.delay_before_start = v.map(|x| x.into());
            self
        }

        /// Sets the value of [demands][crate::model::shipment_route::Visit::demands].
        #[deprecated]
        pub fn set_demands<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::CapacityQuantity>,
        {
            use std::iter::Iterator;
            self.demands = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for Visit {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.ShipmentRoute.Visit"
        }
    }

    /// Transition between two events on the route. See the description of
    /// [ShipmentRoute][google.cloud.optimization.v1.ShipmentRoute].
    ///
    /// If the vehicle does not have a `start_location` and/or `end_location`, the
    /// corresponding travel metrics are 0.
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute]: crate::model::ShipmentRoute
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct Transition {
        /// Travel duration during this transition.
        pub travel_duration: std::option::Option<wkt::Duration>,

        /// Distance traveled during the transition.
        pub travel_distance_meters: f64,

        /// When traffic is requested via
        /// [OptimizeToursRequest.consider_road_traffic]
        /// [google.cloud.optimization.v1.OptimizeToursRequest.consider_road_traffic],
        /// and the traffic info couldn't be retrieved for a `Transition`, this
        /// boolean is set to true. This may be temporary (rare hiccup in the
        /// realtime traffic servers) or permanent (no data for this location).
        pub traffic_info_unavailable: bool,

        /// Sum of the delay durations applied to this transition. If any, the delay
        /// starts exactly `delay_duration` seconds before the next event (visit or
        /// vehicle end). See
        /// [TransitionAttributes.delay][google.cloud.optimization.v1.TransitionAttributes.delay].
        ///
        /// [google.cloud.optimization.v1.TransitionAttributes.delay]: crate::model::TransitionAttributes::delay
        pub delay_duration: std::option::Option<wkt::Duration>,

        /// Sum of the duration of the breaks occurring during this transition, if
        /// any. Details about each break's start time and duration are stored in
        /// [ShipmentRoute.breaks][google.cloud.optimization.v1.ShipmentRoute.breaks].
        ///
        /// [google.cloud.optimization.v1.ShipmentRoute.breaks]: crate::model::ShipmentRoute::breaks
        pub break_duration: std::option::Option<wkt::Duration>,

        /// Time spent waiting during this transition. Wait duration corresponds to
        /// idle time and does not include break time. Also note that this wait time
        /// may be split into several non-contiguous intervals.
        pub wait_duration: std::option::Option<wkt::Duration>,

        /// Total duration of the transition, provided for convenience. It is equal
        /// to:
        ///
        /// * next visit `start_time` (or `vehicle_end_time` if this is the last
        ///   transition) - this transition's `start_time`;
        /// * if `ShipmentRoute.has_traffic_infeasibilities` is false, the following
        ///   additionally holds: `total_duration = travel_duration + delay_duration
        ///
        /// + break_duration + wait_duration`.
        pub total_duration: std::option::Option<wkt::Duration>,

        /// Start time of this transition.
        pub start_time: std::option::Option<wkt::Timestamp>,

        /// The encoded polyline representation of the route followed during the
        /// transition.
        /// This field is only populated if [populate_transition_polylines]
        /// [google.cloud.optimization.v1.OptimizeToursRequest.populate_transition_polylines]
        /// is set to true.
        pub route_polyline: std::option::Option<crate::model::shipment_route::EncodedPolyline>,

        /// Vehicle loads during this transition, for each type that either appears
        /// in this vehicle's
        /// [Vehicle.load_limits][google.cloud.optimization.v1.Vehicle.load_limits],
        /// or that have non-zero
        /// [Shipment.load_demands][google.cloud.optimization.v1.Shipment.load_demands]
        /// on some shipment performed on this route.
        ///
        /// The loads during the first transition are the starting loads of the
        /// vehicle route. Then, after each visit, the visit's `load_demands` are
        /// either added or subtracted to get the next transition's loads, depending
        /// on whether the visit was a pickup or a delivery.
        ///
        /// [google.cloud.optimization.v1.Shipment.load_demands]: crate::model::Shipment::load_demands
        /// [google.cloud.optimization.v1.Vehicle.load_limits]: crate::model::Vehicle::load_limits
        pub vehicle_loads: std::collections::HashMap<
            std::string::String,
            crate::model::shipment_route::VehicleLoad,
        >,

        /// Deprecated: Use
        /// [Transition.vehicle_loads][google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads]
        /// instead.
        ///
        /// [google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads]: crate::model::shipment_route::Transition::vehicle_loads
        #[deprecated]
        pub loads: std::vec::Vec<crate::model::CapacityQuantity>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Transition {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [travel_duration][crate::model::shipment_route::Transition::travel_duration].
        pub fn set_travel_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.travel_duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [travel_duration][crate::model::shipment_route::Transition::travel_duration].
        pub fn set_or_clear_travel_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.travel_duration = v.map(|x| x.into());
            self
        }

        /// Sets the value of [travel_distance_meters][crate::model::shipment_route::Transition::travel_distance_meters].
        pub fn set_travel_distance_meters<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
            self.travel_distance_meters = v.into();
            self
        }

        /// Sets the value of [traffic_info_unavailable][crate::model::shipment_route::Transition::traffic_info_unavailable].
        pub fn set_traffic_info_unavailable<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
            self.traffic_info_unavailable = v.into();
            self
        }

        /// Sets the value of [delay_duration][crate::model::shipment_route::Transition::delay_duration].
        pub fn set_delay_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.delay_duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [delay_duration][crate::model::shipment_route::Transition::delay_duration].
        pub fn set_or_clear_delay_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.delay_duration = v.map(|x| x.into());
            self
        }

        /// Sets the value of [break_duration][crate::model::shipment_route::Transition::break_duration].
        pub fn set_break_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.break_duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [break_duration][crate::model::shipment_route::Transition::break_duration].
        pub fn set_or_clear_break_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.break_duration = v.map(|x| x.into());
            self
        }

        /// Sets the value of [wait_duration][crate::model::shipment_route::Transition::wait_duration].
        pub fn set_wait_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.wait_duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [wait_duration][crate::model::shipment_route::Transition::wait_duration].
        pub fn set_or_clear_wait_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.wait_duration = v.map(|x| x.into());
            self
        }

        /// Sets the value of [total_duration][crate::model::shipment_route::Transition::total_duration].
        pub fn set_total_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.total_duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [total_duration][crate::model::shipment_route::Transition::total_duration].
        pub fn set_or_clear_total_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.total_duration = v.map(|x| x.into());
            self
        }

        /// Sets the value of [start_time][crate::model::shipment_route::Transition::start_time].
        pub fn set_start_time<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.start_time = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [start_time][crate::model::shipment_route::Transition::start_time].
        pub fn set_or_clear_start_time<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.start_time = v.map(|x| x.into());
            self
        }

        /// Sets the value of [route_polyline][crate::model::shipment_route::Transition::route_polyline].
        pub fn set_route_polyline<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::shipment_route::EncodedPolyline>,
        {
            self.route_polyline = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [route_polyline][crate::model::shipment_route::Transition::route_polyline].
        pub fn set_or_clear_route_polyline<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::shipment_route::EncodedPolyline>,
        {
            self.route_polyline = v.map(|x| x.into());
            self
        }

        /// Sets the value of [vehicle_loads][crate::model::shipment_route::Transition::vehicle_loads].
        pub fn set_vehicle_loads<T, K, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = (K, V)>,
            K: std::convert::Into<std::string::String>,
            V: std::convert::Into<crate::model::shipment_route::VehicleLoad>,
        {
            use std::iter::Iterator;
            self.vehicle_loads = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
            self
        }

        /// Sets the value of [loads][crate::model::shipment_route::Transition::loads].
        #[deprecated]
        pub fn set_loads<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::CapacityQuantity>,
        {
            use std::iter::Iterator;
            self.loads = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for Transition {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.ShipmentRoute.Transition"
        }
    }

    /// Reports the actual load of the vehicle at some point along the route,
    /// for a given type (see
    /// [Transition.vehicle_loads][google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads]).
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads]: crate::model::shipment_route::Transition::vehicle_loads
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct VehicleLoad {
        /// The amount of load on the vehicle, for the given type. The unit of load
        /// is usually indicated by the type. See
        /// [Transition.vehicle_loads][google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads].
        ///
        /// [google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads]: crate::model::shipment_route::Transition::vehicle_loads
        pub amount: i64,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl VehicleLoad {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [amount][crate::model::shipment_route::VehicleLoad::amount].
        pub fn set_amount<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
            self.amount = v.into();
            self
        }
    }

    impl wkt::message::Message for VehicleLoad {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.ShipmentRoute.VehicleLoad"
        }
    }

    /// The encoded representation of a polyline. More information on polyline
    /// encoding can be found here:
    /// <https://developers.google.com/maps/documentation/utilities/polylinealgorithm>
    /// <https://developers.google.com/maps/documentation/javascript/reference/geometry#encoding>.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct EncodedPolyline {
        /// String representing encoded points of the polyline.
        pub points: std::string::String,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl EncodedPolyline {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [points][crate::model::shipment_route::EncodedPolyline::points].
        pub fn set_points<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.points = v.into();
            self
        }
    }

    impl wkt::message::Message for EncodedPolyline {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.ShipmentRoute.EncodedPolyline"
        }
    }

    /// Data representing the execution of a break.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct Break {
        /// Start time of a break.
        pub start_time: std::option::Option<wkt::Timestamp>,

        /// Duration of a break.
        pub duration: std::option::Option<wkt::Duration>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Break {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [start_time][crate::model::shipment_route::Break::start_time].
        pub fn set_start_time<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.start_time = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [start_time][crate::model::shipment_route::Break::start_time].
        pub fn set_or_clear_start_time<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Timestamp>,
        {
            self.start_time = v.map(|x| x.into());
            self
        }

        /// Sets the value of [duration][crate::model::shipment_route::Break::duration].
        pub fn set_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [duration][crate::model::shipment_route::Break::duration].
        pub fn set_or_clear_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.duration = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for Break {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.ShipmentRoute.Break"
        }
    }

    /// Deprecated: Use
    /// [ShipmentRoute.Transition][google.cloud.optimization.v1.ShipmentRoute.Transition]
    /// instead. Travel between each visit along the route: from the vehicle's
    /// `start_location` to the first visit's `arrival_location`, then from the
    /// first visit's `departure_location` to the second visit's
    /// `arrival_location`, and so on until the vehicle's `end_location`. This
    /// accounts only for the actual travel between visits, not counting the
    /// waiting time, the time spent performing a visit, nor the distance covered
    /// during a visit.
    ///
    /// Invariant: `travel_steps_size() == visits_size() + 1`.
    ///
    /// If the vehicle does not have a start_ and/or end_location, the
    /// corresponding travel metrics are 0 and/or empty.
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute.Transition]: crate::model::shipment_route::Transition
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    #[deprecated]
    pub struct TravelStep {
        /// Duration of the travel step.
        pub duration: std::option::Option<wkt::Duration>,

        /// Distance traveled during the step.
        pub distance_meters: f64,

        /// When traffic is requested via
        /// [OptimizeToursRequest.consider_road_traffic][google.cloud.optimization.v1.OptimizeToursRequest.consider_road_traffic],
        /// and the traffic info couldn't be retrieved for a TravelStep, this boolean
        /// is set to true. This may be temporary (rare hiccup in the realtime
        /// traffic servers) or permanent (no data for this location).
        ///
        /// [google.cloud.optimization.v1.OptimizeToursRequest.consider_road_traffic]: crate::model::OptimizeToursRequest::consider_road_traffic
        pub traffic_info_unavailable: bool,

        /// The encoded polyline representation of the route followed during the
        /// step.
        ///
        /// This field is only populated if
        /// [OptimizeToursRequest.populate_travel_step_polylines][google.cloud.optimization.v1.OptimizeToursRequest.populate_travel_step_polylines]
        /// is set to true.
        ///
        /// [google.cloud.optimization.v1.OptimizeToursRequest.populate_travel_step_polylines]: crate::model::OptimizeToursRequest::populate_travel_step_polylines
        pub route_polyline: std::option::Option<crate::model::shipment_route::EncodedPolyline>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl TravelStep {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [duration][crate::model::shipment_route::TravelStep::duration].
        pub fn set_duration<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.duration = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [duration][crate::model::shipment_route::TravelStep::duration].
        pub fn set_or_clear_duration<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Duration>,
        {
            self.duration = v.map(|x| x.into());
            self
        }

        /// Sets the value of [distance_meters][crate::model::shipment_route::TravelStep::distance_meters].
        pub fn set_distance_meters<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
            self.distance_meters = v.into();
            self
        }

        /// Sets the value of [traffic_info_unavailable][crate::model::shipment_route::TravelStep::traffic_info_unavailable].
        pub fn set_traffic_info_unavailable<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
            self.traffic_info_unavailable = v.into();
            self
        }

        /// Sets the value of [route_polyline][crate::model::shipment_route::TravelStep::route_polyline].
        pub fn set_route_polyline<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::shipment_route::EncodedPolyline>,
        {
            self.route_polyline = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [route_polyline][crate::model::shipment_route::TravelStep::route_polyline].
        pub fn set_or_clear_route_polyline<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::shipment_route::EncodedPolyline>,
        {
            self.route_polyline = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for TravelStep {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.ShipmentRoute.TravelStep"
        }
    }
}

/// Specifies details of unperformed shipments in a solution. For trivial cases
/// and/or if we are able to identify the cause for skipping, we report the
/// reason here.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct SkippedShipment {
    /// The index corresponds to the index of the shipment in the source
    /// `ShipmentModel`.
    pub index: i32,

    /// Copy of the corresponding
    /// [Shipment.label][google.cloud.optimization.v1.Shipment.label], if specified
    /// in the `Shipment`.
    ///
    /// [google.cloud.optimization.v1.Shipment.label]: crate::model::Shipment::label
    pub label: std::string::String,

    /// A list of reasons that explain why the shipment was skipped. See comment
    /// above `Reason`.
    pub reasons: std::vec::Vec<crate::model::skipped_shipment::Reason>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl SkippedShipment {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [index][crate::model::SkippedShipment::index].
    pub fn set_index<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.index = v.into();
        self
    }

    /// Sets the value of [label][crate::model::SkippedShipment::label].
    pub fn set_label<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.label = v.into();
        self
    }

    /// Sets the value of [reasons][crate::model::SkippedShipment::reasons].
    pub fn set_reasons<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::skipped_shipment::Reason>,
    {
        use std::iter::Iterator;
        self.reasons = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for SkippedShipment {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.SkippedShipment"
    }
}

/// Defines additional types related to [SkippedShipment].
pub mod skipped_shipment {
    #[allow(unused_imports)]
    use super::*;

    /// If we can explain why the shipment was skipped, reasons will be listed
    /// here. If the reason is not the same for all vehicles, `reason` will have
    /// more than 1 element. A skipped shipment cannot have duplicate reasons,
    /// i.e. where all fields are the same except for `example_vehicle_index`.
    /// Example:
    ///
    /// ```norust
    /// reasons {
    ///   code: DEMAND_EXCEEDS_VEHICLE_CAPACITY
    ///   example_vehicle_index: 1
    ///   example_exceeded_capacity_type: "Apples"
    /// }
    /// reasons {
    ///   code: DEMAND_EXCEEDS_VEHICLE_CAPACITY
    ///   example_vehicle_index: 3
    ///   example_exceeded_capacity_type: "Pears"
    /// }
    /// reasons {
    ///   code: CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DISTANCE_LIMIT
    ///   example_vehicle_index: 1
    /// }
    /// ```
    ///
    /// The skipped shipment is incompatible with all vehicles. The reasons may
    /// be different for all vehicles but at least one vehicle's "Apples"
    /// capacity would be exceeded (including vehicle 1), at least one vehicle's
    /// "Pears" capacity would be exceeded (including vehicle 3) and at least one
    /// vehicle's distance limit would be exceeded (including vehicle 1).
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct Reason {
        /// Refer to the comments of Code.
        pub code: crate::model::skipped_shipment::reason::Code,

        /// If the reason is related to a shipment-vehicle incompatibility, this
        /// field provides the index of one relevant vehicle.
        pub example_vehicle_index: std::option::Option<i32>,

        /// If the reason code is `DEMAND_EXCEEDS_VEHICLE_CAPACITY`, documents one
        /// capacity type that is exceeded.
        pub example_exceeded_capacity_type: std::string::String,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Reason {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [code][crate::model::skipped_shipment::Reason::code].
        pub fn set_code<T: std::convert::Into<crate::model::skipped_shipment::reason::Code>>(
            mut self,
            v: T,
        ) -> Self {
            self.code = v.into();
            self
        }

        /// Sets the value of [example_vehicle_index][crate::model::skipped_shipment::Reason::example_vehicle_index].
        pub fn set_example_vehicle_index<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<i32>,
        {
            self.example_vehicle_index = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [example_vehicle_index][crate::model::skipped_shipment::Reason::example_vehicle_index].
        pub fn set_or_clear_example_vehicle_index<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<i32>,
        {
            self.example_vehicle_index = v.map(|x| x.into());
            self
        }

        /// Sets the value of [example_exceeded_capacity_type][crate::model::skipped_shipment::Reason::example_exceeded_capacity_type].
        pub fn set_example_exceeded_capacity_type<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.example_exceeded_capacity_type = v.into();
            self
        }
    }

    impl wkt::message::Message for Reason {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.SkippedShipment.Reason"
        }
    }

    /// Defines additional types related to [Reason].
    pub mod reason {
        #[allow(unused_imports)]
        use super::*;

        /// Code identifying the reason type. The order here is meaningless. In
        /// particular, it gives no indication of whether a given reason will
        /// appear before another in the solution, if both apply.
        ///
        /// # Working with unknown values
        ///
        /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
        /// additional enum variants at any time. Adding new variants is not considered
        /// a breaking change. Applications should write their code in anticipation of:
        ///
        /// - New values appearing in future releases of the client library, **and**
        /// - New values received dynamically, without application changes.
        ///
        /// Please consult the [Working with enums] section in the user guide for some
        /// guidelines.
        ///
        /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum Code {
            /// This should never be used. If we are unable to understand why a
            /// shipment was skipped, we simply return an empty set of reasons.
            Unspecified,
            /// There is no vehicle in the model making all shipments infeasible.
            NoVehicle,
            /// The demand of the shipment exceeds a vehicle's capacity for some
            /// capacity types, one of which is `example_exceeded_capacity_type`.
            DemandExceedsVehicleCapacity,
            /// The minimum distance necessary to perform this shipment, i.e. from
            /// the vehicle's `start_location` to the shipment's pickup and/or delivery
            /// locations and to the vehicle's end location exceeds the vehicle's
            /// `route_distance_limit`.
            ///
            /// Note that for this computation we use the geodesic distances.
            CannotBePerformedWithinVehicleDistanceLimit,
            /// The minimum time necessary to perform this shipment, including travel
            /// time, wait time and service time exceeds the vehicle's
            /// `route_duration_limit`.
            ///
            /// Note: travel time is computed in the best-case scenario, namely as
            /// geodesic distance x 36 m/s (roughly 130 km/hour).
            CannotBePerformedWithinVehicleDurationLimit,
            /// Same as above but we only compare minimum travel time and the
            /// vehicle's `travel_duration_limit`.
            CannotBePerformedWithinVehicleTravelDurationLimit,
            /// The vehicle cannot perform this shipment in the best-case scenario
            /// (see `CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DURATION_LIMIT` for time
            /// computation) if it starts at its earliest start time: the total time
            /// would make the vehicle end after its latest end time.
            CannotBePerformedWithinVehicleTimeWindows,
            /// The `allowed_vehicle_indices` field of the shipment is not empty and
            /// this vehicle does not belong to it.
            VehicleNotAllowed,
            /// If set, the enum was initialized with an unknown value.
            ///
            /// Applications can examine the value using [Code::value] or
            /// [Code::name].
            UnknownValue(code::UnknownValue),
        }

        #[doc(hidden)]
        pub mod code {
            #[allow(unused_imports)]
            use super::*;
            #[derive(Clone, Debug, PartialEq)]
            pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
        }

        impl Code {
            /// Gets the enum value.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the string representation of enums.
            pub fn value(&self) -> std::option::Option<i32> {
                match self {
                    Self::Unspecified => std::option::Option::Some(0),
                    Self::NoVehicle => std::option::Option::Some(1),
                    Self::DemandExceedsVehicleCapacity => std::option::Option::Some(2),
                    Self::CannotBePerformedWithinVehicleDistanceLimit => {
                        std::option::Option::Some(3)
                    }
                    Self::CannotBePerformedWithinVehicleDurationLimit => {
                        std::option::Option::Some(4)
                    }
                    Self::CannotBePerformedWithinVehicleTravelDurationLimit => {
                        std::option::Option::Some(5)
                    }
                    Self::CannotBePerformedWithinVehicleTimeWindows => std::option::Option::Some(6),
                    Self::VehicleNotAllowed => std::option::Option::Some(7),
                    Self::UnknownValue(u) => u.0.value(),
                }
            }

            /// Gets the enum value as a string.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the integer representation of enums.
            pub fn name(&self) -> std::option::Option<&str> {
                match self {
                    Self::Unspecified => std::option::Option::Some("CODE_UNSPECIFIED"),
                    Self::NoVehicle => std::option::Option::Some("NO_VEHICLE"),
                    Self::DemandExceedsVehicleCapacity => {
                        std::option::Option::Some("DEMAND_EXCEEDS_VEHICLE_CAPACITY")
                    }
                    Self::CannotBePerformedWithinVehicleDistanceLimit => std::option::Option::Some(
                        "CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DISTANCE_LIMIT",
                    ),
                    Self::CannotBePerformedWithinVehicleDurationLimit => std::option::Option::Some(
                        "CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DURATION_LIMIT",
                    ),
                    Self::CannotBePerformedWithinVehicleTravelDurationLimit => {
                        std::option::Option::Some(
                            "CANNOT_BE_PERFORMED_WITHIN_VEHICLE_TRAVEL_DURATION_LIMIT",
                        )
                    }
                    Self::CannotBePerformedWithinVehicleTimeWindows => {
                        std::option::Option::Some("CANNOT_BE_PERFORMED_WITHIN_VEHICLE_TIME_WINDOWS")
                    }
                    Self::VehicleNotAllowed => std::option::Option::Some("VEHICLE_NOT_ALLOWED"),
                    Self::UnknownValue(u) => u.0.name(),
                }
            }
        }

        impl std::default::Default for Code {
            fn default() -> Self {
                use std::convert::From;
                Self::from(0)
            }
        }

        impl std::fmt::Display for Code {
            fn fmt(
                &self,
                f: &mut std::fmt::Formatter<'_>,
            ) -> std::result::Result<(), std::fmt::Error> {
                wkt::internal::display_enum(f, self.name(), self.value())
            }
        }

        impl std::convert::From<i32> for Code {
            fn from(value: i32) -> Self {
                match value {
                    0 => Self::Unspecified,
                    1 => Self::NoVehicle,
                    2 => Self::DemandExceedsVehicleCapacity,
                    3 => Self::CannotBePerformedWithinVehicleDistanceLimit,
                    4 => Self::CannotBePerformedWithinVehicleDurationLimit,
                    5 => Self::CannotBePerformedWithinVehicleTravelDurationLimit,
                    6 => Self::CannotBePerformedWithinVehicleTimeWindows,
                    7 => Self::VehicleNotAllowed,
                    _ => Self::UnknownValue(code::UnknownValue(
                        wkt::internal::UnknownEnumValue::Integer(value),
                    )),
                }
            }
        }

        impl std::convert::From<&str> for Code {
            fn from(value: &str) -> Self {
                use std::string::ToString;
                match value {
                    "CODE_UNSPECIFIED" => Self::Unspecified,
                    "NO_VEHICLE" => Self::NoVehicle,
                    "DEMAND_EXCEEDS_VEHICLE_CAPACITY" => Self::DemandExceedsVehicleCapacity,
                    "CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DISTANCE_LIMIT" => {
                        Self::CannotBePerformedWithinVehicleDistanceLimit
                    }
                    "CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DURATION_LIMIT" => {
                        Self::CannotBePerformedWithinVehicleDurationLimit
                    }
                    "CANNOT_BE_PERFORMED_WITHIN_VEHICLE_TRAVEL_DURATION_LIMIT" => {
                        Self::CannotBePerformedWithinVehicleTravelDurationLimit
                    }
                    "CANNOT_BE_PERFORMED_WITHIN_VEHICLE_TIME_WINDOWS" => {
                        Self::CannotBePerformedWithinVehicleTimeWindows
                    }
                    "VEHICLE_NOT_ALLOWED" => Self::VehicleNotAllowed,
                    _ => Self::UnknownValue(code::UnknownValue(
                        wkt::internal::UnknownEnumValue::String(value.to_string()),
                    )),
                }
            }
        }

        impl serde::ser::Serialize for Code {
            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
            where
                S: serde::Serializer,
            {
                match self {
                    Self::Unspecified => serializer.serialize_i32(0),
                    Self::NoVehicle => serializer.serialize_i32(1),
                    Self::DemandExceedsVehicleCapacity => serializer.serialize_i32(2),
                    Self::CannotBePerformedWithinVehicleDistanceLimit => {
                        serializer.serialize_i32(3)
                    }
                    Self::CannotBePerformedWithinVehicleDurationLimit => {
                        serializer.serialize_i32(4)
                    }
                    Self::CannotBePerformedWithinVehicleTravelDurationLimit => {
                        serializer.serialize_i32(5)
                    }
                    Self::CannotBePerformedWithinVehicleTimeWindows => serializer.serialize_i32(6),
                    Self::VehicleNotAllowed => serializer.serialize_i32(7),
                    Self::UnknownValue(u) => u.0.serialize(serializer),
                }
            }
        }

        impl<'de> serde::de::Deserialize<'de> for Code {
            fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
            where
                D: serde::Deserializer<'de>,
            {
                deserializer.deserialize_any(wkt::internal::EnumVisitor::<Code>::new(
                    ".google.cloud.optimization.v1.SkippedShipment.Reason.Code",
                ))
            }
        }
    }
}

/// Aggregated metrics for
/// [ShipmentRoute][google.cloud.optimization.v1.ShipmentRoute] (resp. for
/// [OptimizeToursResponse][google.cloud.optimization.v1.OptimizeToursResponse]
/// over all [Transition][google.cloud.optimization.v1.ShipmentRoute.Transition]
/// and/or [Visit][google.cloud.optimization.v1.ShipmentRoute.Visit] (resp. over
/// all [ShipmentRoute][google.cloud.optimization.v1.ShipmentRoute]) elements.
///
/// [google.cloud.optimization.v1.OptimizeToursResponse]: crate::model::OptimizeToursResponse
/// [google.cloud.optimization.v1.ShipmentRoute]: crate::model::ShipmentRoute
/// [google.cloud.optimization.v1.ShipmentRoute.Transition]: crate::model::shipment_route::Transition
/// [google.cloud.optimization.v1.ShipmentRoute.Visit]: crate::model::shipment_route::Visit
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AggregatedMetrics {
    /// Number of shipments performed. Note that a pickup and delivery pair only
    /// counts once.
    pub performed_shipment_count: i32,

    /// Total travel duration for a route or a solution.
    pub travel_duration: std::option::Option<wkt::Duration>,

    /// Total wait duration for a route or a solution.
    pub wait_duration: std::option::Option<wkt::Duration>,

    /// Total delay duration for a route or a solution.
    pub delay_duration: std::option::Option<wkt::Duration>,

    /// Total break duration for a route or a solution.
    pub break_duration: std::option::Option<wkt::Duration>,

    /// Total visit duration for a route or a solution.
    pub visit_duration: std::option::Option<wkt::Duration>,

    /// The total duration should be equal to the sum of all durations above.
    /// For routes, it also corresponds to:
    /// [ShipmentRoute.vehicle_end_time][google.cloud.optimization.v1.ShipmentRoute.vehicle_end_time]
    /// `-`
    /// [ShipmentRoute.vehicle_start_time][google.cloud.optimization.v1.ShipmentRoute.vehicle_start_time]
    ///
    /// [google.cloud.optimization.v1.ShipmentRoute.vehicle_end_time]: crate::model::ShipmentRoute::vehicle_end_time
    /// [google.cloud.optimization.v1.ShipmentRoute.vehicle_start_time]: crate::model::ShipmentRoute::vehicle_start_time
    pub total_duration: std::option::Option<wkt::Duration>,

    /// Total travel distance for a route or a solution.
    pub travel_distance_meters: f64,

    /// Maximum load achieved over the entire route (resp. solution), for each of
    /// the quantities on this route (resp. solution), computed as the maximum over
    /// all
    /// [Transition.vehicle_loads][google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads]
    /// (resp.
    /// [ShipmentRoute.metrics.max_loads][google.cloud.optimization.v1.AggregatedMetrics.max_loads].
    ///
    /// [google.cloud.optimization.v1.AggregatedMetrics.max_loads]: crate::model::AggregatedMetrics::max_loads
    /// [google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads]: crate::model::shipment_route::Transition::vehicle_loads
    pub max_loads:
        std::collections::HashMap<std::string::String, crate::model::shipment_route::VehicleLoad>,

    /// Deprecated: Use
    /// [ShipmentRoute.route_costs][google.cloud.optimization.v1.ShipmentRoute.route_costs]
    /// and
    /// [OptimizeToursResponse.Metrics.costs][google.cloud.optimization.v1.OptimizeToursResponse.Metrics.costs]
    /// instead.
    ///
    /// [google.cloud.optimization.v1.OptimizeToursResponse.Metrics.costs]: crate::model::optimize_tours_response::Metrics::costs
    /// [google.cloud.optimization.v1.ShipmentRoute.route_costs]: crate::model::ShipmentRoute::route_costs
    #[deprecated]
    pub costs: std::collections::HashMap<std::string::String, f64>,

    /// Deprecated: Use
    /// [ShipmentRoute.route_total_cost][google.cloud.optimization.v1.ShipmentRoute.route_total_cost]
    /// and
    /// [OptimizeToursResponse.Metrics.total_cost][google.cloud.optimization.v1.OptimizeToursResponse.Metrics.total_cost]
    /// instead.
    ///
    /// [google.cloud.optimization.v1.OptimizeToursResponse.Metrics.total_cost]: crate::model::optimize_tours_response::Metrics::total_cost
    /// [google.cloud.optimization.v1.ShipmentRoute.route_total_cost]: crate::model::ShipmentRoute::route_total_cost
    #[deprecated]
    pub total_cost: f64,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AggregatedMetrics {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [performed_shipment_count][crate::model::AggregatedMetrics::performed_shipment_count].
    pub fn set_performed_shipment_count<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.performed_shipment_count = v.into();
        self
    }

    /// Sets the value of [travel_duration][crate::model::AggregatedMetrics::travel_duration].
    pub fn set_travel_duration<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.travel_duration = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [travel_duration][crate::model::AggregatedMetrics::travel_duration].
    pub fn set_or_clear_travel_duration<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.travel_duration = v.map(|x| x.into());
        self
    }

    /// Sets the value of [wait_duration][crate::model::AggregatedMetrics::wait_duration].
    pub fn set_wait_duration<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.wait_duration = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [wait_duration][crate::model::AggregatedMetrics::wait_duration].
    pub fn set_or_clear_wait_duration<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.wait_duration = v.map(|x| x.into());
        self
    }

    /// Sets the value of [delay_duration][crate::model::AggregatedMetrics::delay_duration].
    pub fn set_delay_duration<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.delay_duration = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [delay_duration][crate::model::AggregatedMetrics::delay_duration].
    pub fn set_or_clear_delay_duration<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.delay_duration = v.map(|x| x.into());
        self
    }

    /// Sets the value of [break_duration][crate::model::AggregatedMetrics::break_duration].
    pub fn set_break_duration<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.break_duration = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [break_duration][crate::model::AggregatedMetrics::break_duration].
    pub fn set_or_clear_break_duration<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.break_duration = v.map(|x| x.into());
        self
    }

    /// Sets the value of [visit_duration][crate::model::AggregatedMetrics::visit_duration].
    pub fn set_visit_duration<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.visit_duration = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [visit_duration][crate::model::AggregatedMetrics::visit_duration].
    pub fn set_or_clear_visit_duration<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.visit_duration = v.map(|x| x.into());
        self
    }

    /// Sets the value of [total_duration][crate::model::AggregatedMetrics::total_duration].
    pub fn set_total_duration<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.total_duration = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [total_duration][crate::model::AggregatedMetrics::total_duration].
    pub fn set_or_clear_total_duration<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.total_duration = v.map(|x| x.into());
        self
    }

    /// Sets the value of [travel_distance_meters][crate::model::AggregatedMetrics::travel_distance_meters].
    pub fn set_travel_distance_meters<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.travel_distance_meters = v.into();
        self
    }

    /// Sets the value of [max_loads][crate::model::AggregatedMetrics::max_loads].
    pub fn set_max_loads<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::shipment_route::VehicleLoad>,
    {
        use std::iter::Iterator;
        self.max_loads = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [costs][crate::model::AggregatedMetrics::costs].
    #[deprecated]
    pub fn set_costs<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<f64>,
    {
        use std::iter::Iterator;
        self.costs = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [total_cost][crate::model::AggregatedMetrics::total_cost].
    #[deprecated]
    pub fn set_total_cost<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.total_cost = v.into();
        self
    }
}

impl wkt::message::Message for AggregatedMetrics {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.AggregatedMetrics"
    }
}

/// Solution injected in the request including information about which visits
/// must be constrained and how they must be constrained.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct InjectedSolutionConstraint {
    /// Routes of the solution to inject. Some routes may be omitted from the
    /// original solution. The routes and skipped shipments must satisfy the basic
    /// validity assumptions listed for `injected_first_solution_routes`.
    pub routes: std::vec::Vec<crate::model::ShipmentRoute>,

    /// Skipped shipments of the solution to inject. Some may be omitted from the
    /// original solution. See the `routes` field.
    pub skipped_shipments: std::vec::Vec<crate::model::SkippedShipment>,

    /// For zero or more groups of vehicles, specifies when and how much to relax
    /// constraints. If this field is empty, all non-empty vehicle routes are
    /// fully constrained.
    pub constraint_relaxations:
        std::vec::Vec<crate::model::injected_solution_constraint::ConstraintRelaxation>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl InjectedSolutionConstraint {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [routes][crate::model::InjectedSolutionConstraint::routes].
    pub fn set_routes<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::ShipmentRoute>,
    {
        use std::iter::Iterator;
        self.routes = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [skipped_shipments][crate::model::InjectedSolutionConstraint::skipped_shipments].
    pub fn set_skipped_shipments<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::SkippedShipment>,
    {
        use std::iter::Iterator;
        self.skipped_shipments = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [constraint_relaxations][crate::model::InjectedSolutionConstraint::constraint_relaxations].
    pub fn set_constraint_relaxations<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::injected_solution_constraint::ConstraintRelaxation>,
    {
        use std::iter::Iterator;
        self.constraint_relaxations = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for InjectedSolutionConstraint {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.InjectedSolutionConstraint"
    }
}

/// Defines additional types related to [InjectedSolutionConstraint].
pub mod injected_solution_constraint {
    #[allow(unused_imports)]
    use super::*;

    /// For a group of vehicles, specifies at what threshold(s) constraints on
    /// visits will be relaxed and to which level. Shipments listed in
    /// the `skipped_shipment` field are constrained to be skipped; i.e., they
    /// cannot be performed.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct ConstraintRelaxation {
        /// All the visit constraint relaxations that will apply to visits on
        /// routes with vehicles in `vehicle_indices`.
        pub relaxations: std::vec::Vec<
            crate::model::injected_solution_constraint::constraint_relaxation::Relaxation,
        >,

        /// Specifies the vehicle indices to which the visit constraint
        /// `relaxations` apply. If empty, this is considered the default and the
        /// `relaxations` apply to all vehicles that are not specified in other
        /// `constraint_relaxations`. There can be at most one default, i.e., at
        /// most one constraint relaxation field is allowed empty
        /// `vehicle_indices`. A vehicle index can only be listed once, even within
        /// several `constraint_relaxations`.
        ///
        /// A vehicle index is mapped the same as
        /// [ShipmentRoute.vehicle_index][google.cloud.optimization.v1.ShipmentRoute.vehicle_index],
        /// if `interpret_injected_solutions_using_labels` is true (see `fields`
        /// comment).
        ///
        /// [google.cloud.optimization.v1.ShipmentRoute.vehicle_index]: crate::model::ShipmentRoute::vehicle_index
        pub vehicle_indices: std::vec::Vec<i32>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl ConstraintRelaxation {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [relaxations][crate::model::injected_solution_constraint::ConstraintRelaxation::relaxations].
        pub fn set_relaxations<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<
                    crate::model::injected_solution_constraint::constraint_relaxation::Relaxation,
                >,
        {
            use std::iter::Iterator;
            self.relaxations = v.into_iter().map(|i| i.into()).collect();
            self
        }

        /// Sets the value of [vehicle_indices][crate::model::injected_solution_constraint::ConstraintRelaxation::vehicle_indices].
        pub fn set_vehicle_indices<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<i32>,
        {
            use std::iter::Iterator;
            self.vehicle_indices = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for ConstraintRelaxation {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.InjectedSolutionConstraint.ConstraintRelaxation"
        }
    }

    /// Defines additional types related to [ConstraintRelaxation].
    pub mod constraint_relaxation {
        #[allow(unused_imports)]
        use super::*;

        /// If `relaxations` is empty, the start time and sequence of all visits
        /// on `routes` are fully constrained and no new visits may be inserted or
        /// added to those routes. Also, a vehicle's start and end time in
        /// `routes` is fully constrained, unless the vehicle is empty (i.e., has no
        /// visits and has `used_if_route_is_empty` set to false in the model).
        ///
        /// `relaxations(i).level` specifies the constraint relaxation level applied
        /// to a visit #j that satisfies:
        ///
        /// * `route.visits(j).start_time >= relaxations(i).threshold_time` AND
        /// * `j + 1 >= relaxations(i).threshold_visit_count`
        ///
        /// Similarly, the vehicle start is relaxed to `relaxations(i).level` if it
        /// satisfies:
        ///
        /// * `vehicle_start_time >= relaxations(i).threshold_time` AND
        /// * `relaxations(i).threshold_visit_count == 0`
        ///   and the vehicle end is relaxed to `relaxations(i).level` if it satisfies:
        /// * `vehicle_end_time >= relaxations(i).threshold_time` AND
        /// * `route.visits_size() + 1 >= relaxations(i).threshold_visit_count`
        ///
        /// To apply a relaxation level if a visit meets the `threshold_visit_count`
        /// OR the `threshold_time` add two `relaxations` with the same `level`:
        /// one with only `threshold_visit_count` set and the other with only
        /// `threshold_time` set. If a visit satisfies the conditions of multiple
        /// `relaxations`, the most relaxed level applies. As a result, from the
        /// vehicle start through the route visits in order to the vehicle end, the
        /// relaxation level becomes more relaxed: i.e., the relaxation level is
        /// non-decreasing as the route progresses.
        ///
        /// The timing and sequence of route visits that do not satisfy the
        /// threshold conditions of any `relaxations` are fully constrained
        /// and no visits may be inserted into these sequences. Also, if a
        /// vehicle start or end does not satisfy the conditions of any
        /// relaxation the time is fixed, unless the vehicle is empty.
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct Relaxation {

            /// The constraint relaxation level that applies when the conditions
            /// at or after `threshold_time` AND at least `threshold_visit_count` are
            /// satisfied.
            pub level: crate::model::injected_solution_constraint::constraint_relaxation::relaxation::Level,

            /// The time at or after which the relaxation `level` may be applied.
            pub threshold_time: std::option::Option<wkt::Timestamp>,

            /// The number of visits at or after which the relaxation `level` may be
            /// applied. If `threshold_visit_count` is 0 (or unset), the `level` may be
            /// applied directly at the vehicle start.
            ///
            /// If it is `route.visits_size() + 1`, the `level` may only be applied to
            /// the vehicle end. If it is more than `route.visits_size() + 1`,
            /// `level` is not applied at all for that route.
            pub threshold_visit_count: i32,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl Relaxation {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [level][crate::model::injected_solution_constraint::constraint_relaxation::Relaxation::level].
            pub fn set_level<T: std::convert::Into<crate::model::injected_solution_constraint::constraint_relaxation::relaxation::Level>>(mut self, v: T) -> Self{
                self.level = v.into();
                self
            }

            /// Sets the value of [threshold_time][crate::model::injected_solution_constraint::constraint_relaxation::Relaxation::threshold_time].
            pub fn set_threshold_time<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<wkt::Timestamp>,
            {
                self.threshold_time = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [threshold_time][crate::model::injected_solution_constraint::constraint_relaxation::Relaxation::threshold_time].
            pub fn set_or_clear_threshold_time<T>(mut self, v: std::option::Option<T>) -> Self
            where
                T: std::convert::Into<wkt::Timestamp>,
            {
                self.threshold_time = v.map(|x| x.into());
                self
            }

            /// Sets the value of [threshold_visit_count][crate::model::injected_solution_constraint::constraint_relaxation::Relaxation::threshold_visit_count].
            pub fn set_threshold_visit_count<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
                self.threshold_visit_count = v.into();
                self
            }
        }

        impl wkt::message::Message for Relaxation {
            fn typename() -> &'static str {
                "type.googleapis.com/google.cloud.optimization.v1.InjectedSolutionConstraint.ConstraintRelaxation.Relaxation"
            }
        }

        /// Defines additional types related to [Relaxation].
        pub mod relaxation {
            #[allow(unused_imports)]
            use super::*;

            /// Expresses the different constraint relaxation levels, which are
            /// applied for a visit and those that follow when it satisfies the
            /// threshold conditions.
            ///
            /// The enumeration below is in order of increasing relaxation.
            ///
            /// # Working with unknown values
            ///
            /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
            /// additional enum variants at any time. Adding new variants is not considered
            /// a breaking change. Applications should write their code in anticipation of:
            ///
            /// - New values appearing in future releases of the client library, **and**
            /// - New values received dynamically, without application changes.
            ///
            /// Please consult the [Working with enums] section in the user guide for some
            /// guidelines.
            ///
            /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
            #[derive(Clone, Debug, PartialEq)]
            #[non_exhaustive]
            pub enum Level {
                /// Implicit default relaxation level: no constraints are relaxed,
                /// i.e., all visits are fully constrained.
                ///
                /// This value must not be explicitly used in `level`.
                Unspecified,
                /// Visit start times and vehicle start/end times will be relaxed, but
                /// each visit remains bound to the same vehicle and the visit sequence
                /// must be observed: no visit can be inserted between them or before
                /// them.
                RelaxVisitTimesAfterThreshold,
                /// Same as `RELAX_VISIT_TIMES_AFTER_THRESHOLD`, but the visit sequence
                /// is also relaxed: visits can only be performed by this vehicle, but
                /// can potentially become unperformed.
                RelaxVisitTimesAndSequenceAfterThreshold,
                /// Same as `RELAX_VISIT_TIMES_AND_SEQUENCE_AFTER_THRESHOLD`, but the
                /// vehicle is also relaxed: visits are completely free at or after the
                /// threshold time and can potentially become unperformed.
                RelaxAllAfterThreshold,
                /// If set, the enum was initialized with an unknown value.
                ///
                /// Applications can examine the value using [Level::value] or
                /// [Level::name].
                UnknownValue(level::UnknownValue),
            }

            #[doc(hidden)]
            pub mod level {
                #[allow(unused_imports)]
                use super::*;
                #[derive(Clone, Debug, PartialEq)]
                pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
            }

            impl Level {
                /// Gets the enum value.
                ///
                /// Returns `None` if the enum contains an unknown value deserialized from
                /// the string representation of enums.
                pub fn value(&self) -> std::option::Option<i32> {
                    match self {
                        Self::Unspecified => std::option::Option::Some(0),
                        Self::RelaxVisitTimesAfterThreshold => std::option::Option::Some(1),
                        Self::RelaxVisitTimesAndSequenceAfterThreshold => {
                            std::option::Option::Some(2)
                        }
                        Self::RelaxAllAfterThreshold => std::option::Option::Some(3),
                        Self::UnknownValue(u) => u.0.value(),
                    }
                }

                /// Gets the enum value as a string.
                ///
                /// Returns `None` if the enum contains an unknown value deserialized from
                /// the integer representation of enums.
                pub fn name(&self) -> std::option::Option<&str> {
                    match self {
                        Self::Unspecified => std::option::Option::Some("LEVEL_UNSPECIFIED"),
                        Self::RelaxVisitTimesAfterThreshold => {
                            std::option::Option::Some("RELAX_VISIT_TIMES_AFTER_THRESHOLD")
                        }
                        Self::RelaxVisitTimesAndSequenceAfterThreshold => {
                            std::option::Option::Some(
                                "RELAX_VISIT_TIMES_AND_SEQUENCE_AFTER_THRESHOLD",
                            )
                        }
                        Self::RelaxAllAfterThreshold => {
                            std::option::Option::Some("RELAX_ALL_AFTER_THRESHOLD")
                        }
                        Self::UnknownValue(u) => u.0.name(),
                    }
                }
            }

            impl std::default::Default for Level {
                fn default() -> Self {
                    use std::convert::From;
                    Self::from(0)
                }
            }

            impl std::fmt::Display for Level {
                fn fmt(
                    &self,
                    f: &mut std::fmt::Formatter<'_>,
                ) -> std::result::Result<(), std::fmt::Error> {
                    wkt::internal::display_enum(f, self.name(), self.value())
                }
            }

            impl std::convert::From<i32> for Level {
                fn from(value: i32) -> Self {
                    match value {
                        0 => Self::Unspecified,
                        1 => Self::RelaxVisitTimesAfterThreshold,
                        2 => Self::RelaxVisitTimesAndSequenceAfterThreshold,
                        3 => Self::RelaxAllAfterThreshold,
                        _ => Self::UnknownValue(level::UnknownValue(
                            wkt::internal::UnknownEnumValue::Integer(value),
                        )),
                    }
                }
            }

            impl std::convert::From<&str> for Level {
                fn from(value: &str) -> Self {
                    use std::string::ToString;
                    match value {
                        "LEVEL_UNSPECIFIED" => Self::Unspecified,
                        "RELAX_VISIT_TIMES_AFTER_THRESHOLD" => Self::RelaxVisitTimesAfterThreshold,
                        "RELAX_VISIT_TIMES_AND_SEQUENCE_AFTER_THRESHOLD" => {
                            Self::RelaxVisitTimesAndSequenceAfterThreshold
                        }
                        "RELAX_ALL_AFTER_THRESHOLD" => Self::RelaxAllAfterThreshold,
                        _ => Self::UnknownValue(level::UnknownValue(
                            wkt::internal::UnknownEnumValue::String(value.to_string()),
                        )),
                    }
                }
            }

            impl serde::ser::Serialize for Level {
                fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
                where
                    S: serde::Serializer,
                {
                    match self {
                        Self::Unspecified => serializer.serialize_i32(0),
                        Self::RelaxVisitTimesAfterThreshold => serializer.serialize_i32(1),
                        Self::RelaxVisitTimesAndSequenceAfterThreshold => {
                            serializer.serialize_i32(2)
                        }
                        Self::RelaxAllAfterThreshold => serializer.serialize_i32(3),
                        Self::UnknownValue(u) => u.0.serialize(serializer),
                    }
                }
            }

            impl<'de> serde::de::Deserialize<'de> for Level {
                fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
                where
                    D: serde::Deserializer<'de>,
                {
                    deserializer.deserialize_any(wkt::internal::EnumVisitor::<Level>::new(
                        ".google.cloud.optimization.v1.InjectedSolutionConstraint.ConstraintRelaxation.Relaxation.Level"))
                }
            }
        }
    }
}

/// Describes an error encountered when validating an `OptimizeToursRequest`.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct OptimizeToursValidationError {
    /// A validation error is defined by the pair (`code`, `display_name`) which
    /// are always present.
    ///
    /// Other fields (below) provide more context about the error.
    ///
    /// *MULTIPLE ERRORS*:
    /// When there are multiple errors, the validation process tries to output
    /// several of them. Much like a compiler, this is an imperfect process. Some
    /// validation errors will be "fatal", meaning that they stop the entire
    /// validation process. This is the case for `display_name="UNSPECIFIED"`
    /// errors, among others. Some may cause the validation process to skip other
    /// errors.
    ///
    /// *STABILITY*:
    /// `code` and `display_name` should be very stable. But new codes and
    /// display names may appear over time, which may cause a given (invalid)
    /// request to yield a different (`code`, `display_name`) pair because the new
    /// error hid the old one (see "MULTIPLE ERRORS").
    ///
    /// *REFERENCE*: A list of all (code, name) pairs:
    ///
    /// * UNSPECIFIED = 0;
    ///
    /// * VALIDATION_TIMEOUT_ERROR = 10; Validation couldn't be completed within
    ///   the deadline.
    ///
    /// * REQUEST_OPTIONS_ERROR = 12;
    ///
    ///   * REQUEST_OPTIONS_INVALID_SOLVING_MODE = 1201;
    ///   * REQUEST_OPTIONS_INVALID_MAX_VALIDATION_ERRORS = 1203;
    ///   * REQUEST_OPTIONS_INVALID_GEODESIC_METERS_PER_SECOND = 1204;
    ///   * REQUEST_OPTIONS_GEODESIC_METERS_PER_SECOND_TOO_SMALL = 1205;
    ///   * REQUEST_OPTIONS_MISSING_GEODESIC_METERS_PER_SECOND = 1206;
    ///   * REQUEST_OPTIONS_POPULATE_PATHFINDER_TRIPS_AND_GEODESIC_DISTANCE
    ///     = 1207;
    ///   * REQUEST_OPTIONS_COST_MODEL_OPTIONS_AND_GEODESIC_DISTANCE = 1208;
    ///   * REQUEST_OPTIONS_TRAVEL_MODE_INCOMPATIBLE_WITH_TRAFFIC = 1211;
    ///   * REQUEST_OPTIONS_MULTIPLE_TRAFFIC_FLAVORS = 1212;
    ///   * REQUEST_OPTIONS_INVALID_TRAFFIC_FLAVOR = 1213;
    ///   * REQUEST_OPTIONS_TRAFFIC_ENABLED_WITHOUT_GLOBAL_START_TIME = 1214;
    ///   * REQUEST_OPTIONS_TRAFFIC_ENABLED_WITH_PRECEDENCES = 1215;
    ///   * REQUEST_OPTIONS_TRAFFIC_PREFILL_MODE_INVALID = 1216;
    ///   * REQUEST_OPTIONS_TRAFFIC_PREFILL_ENABLED_WITHOUT_TRAFFIC = 1217;
    /// * INJECTED_SOLUTION_ERROR = 20;
    ///
    ///   * INJECTED_SOLUTION_MISSING_LABEL = 2000;
    ///   * INJECTED_SOLUTION_DUPLICATE_LABEL = 2001;
    ///   * INJECTED_SOLUTION_AMBIGUOUS_INDEX = 2002;
    ///   * INJECTED_SOLUTION_INFEASIBLE_AFTER_GETTING_TRAVEL_TIMES = 2003;
    ///   * INJECTED_SOLUTION_TRANSITION_INCONSISTENT_WITH_ACTUAL_TRAVEL = 2004;
    ///   * INJECTED_SOLUTION_CONCURRENT_SOLUTION_TYPES = 2005;
    ///   * INJECTED_SOLUTION_MORE_THAN_ONE_PER_TYPE = 2006;
    ///   * INJECTED_SOLUTION_REFRESH_WITHOUT_POPULATE = 2008;
    ///   * INJECTED_SOLUTION_CONSTRAINED_ROUTE_PORTION_INFEASIBLE = 2010;
    /// * SHIPMENT_MODEL_ERROR = 22;
    ///
    ///   * SHIPMENT_MODEL_TOO_LARGE = 2200;
    ///   * SHIPMENT_MODEL_TOO_MANY_CAPACITY_TYPES = 2201;
    ///   * SHIPMENT_MODEL_GLOBAL_START_TIME_NEGATIVE_OR_NAN = 2202;
    ///   * SHIPMENT_MODEL_GLOBAL_END_TIME_TOO_LARGE_OR_NAN = 2203;
    ///   * SHIPMENT_MODEL_GLOBAL_START_TIME_AFTER_GLOBAL_END_TIME = 2204;
    ///   * SHIPMENT_MODEL_GLOBAL_DURATION_TOO_LONG = 2205;
    ///   * SHIPMENT_MODEL_MAX_ACTIVE_VEHICLES_NOT_POSITIVE = 2206;
    ///   * SHIPMENT_MODEL_DURATION_MATRIX_TOO_LARGE = 2207;
    /// * INDEX_ERROR = 24;
    ///
    /// * TAG_ERROR = 26;
    ///
    /// * TIME_WINDOW_ERROR = 28;
    ///
    ///   * TIME_WINDOW_INVALID_START_TIME = 2800;
    ///   * TIME_WINDOW_INVALID_END_TIME = 2801;
    ///   * TIME_WINDOW_INVALID_SOFT_START_TIME = 2802;
    ///   * TIME_WINDOW_INVALID_SOFT_END_TIME = 2803;
    ///   * TIME_WINDOW_OUTSIDE_GLOBAL_TIME_WINDOW = 2804;
    ///   * TIME_WINDOW_START_TIME_AFTER_END_TIME = 2805;
    ///   * TIME_WINDOW_INVALID_COST_PER_HOUR_BEFORE_SOFT_START_TIME = 2806;
    ///   * TIME_WINDOW_INVALID_COST_PER_HOUR_AFTER_SOFT_END_TIME = 2807;
    ///   * TIME_WINDOW_COST_BEFORE_SOFT_START_TIME_WITHOUT_SOFT_START_TIME
    ///     = 2808;
    ///   * TIME_WINDOW_COST_AFTER_SOFT_END_TIME_WITHOUT_SOFT_END_TIME = 2809;
    ///   * TIME_WINDOW_SOFT_START_TIME_WITHOUT_COST_BEFORE_SOFT_START_TIME
    ///     = 2810;
    ///   * TIME_WINDOW_SOFT_END_TIME_WITHOUT_COST_AFTER_SOFT_END_TIME = 2811;
    ///   * TIME_WINDOW_OVERLAPPING_ADJACENT_OR_EARLIER_THAN_PREVIOUS = 2812;
    ///   * TIME_WINDOW_START_TIME_AFTER_SOFT_START_TIME = 2813;
    ///   * TIME_WINDOW_SOFT_START_TIME_AFTER_END_TIME = 2814;
    ///   * TIME_WINDOW_START_TIME_AFTER_SOFT_END_TIME = 2815;
    ///   * TIME_WINDOW_SOFT_END_TIME_AFTER_END_TIME = 2816;
    ///   * TIME_WINDOW_COST_BEFORE_SOFT_START_TIME_SET_AND_MULTIPLE_WINDOWS
    ///     = 2817;
    ///   * TIME_WINDOW_COST_AFTER_SOFT_END_TIME_SET_AND_MULTIPLE_WINDOWS = 2818;
    ///   * TRANSITION_ATTRIBUTES_ERROR = 30;
    ///   * TRANSITION_ATTRIBUTES_INVALID_COST = 3000;
    ///   * TRANSITION_ATTRIBUTES_INVALID_COST_PER_KILOMETER = 3001;
    ///   * TRANSITION_ATTRIBUTES_DUPLICATE_TAG_PAIR = 3002;
    ///   * TRANSITION_ATTRIBUTES_DISTANCE_LIMIT_MAX_METERS_UNSUPPORTED = 3003;
    ///   * TRANSITION_ATTRIBUTES_UNSPECIFIED_SOURCE_TAGS = 3004;
    ///   * TRANSITION_ATTRIBUTES_CONFLICTING_SOURCE_TAGS_FIELDS = 3005;
    ///   * TRANSITION_ATTRIBUTES_UNSPECIFIED_DESTINATION_TAGS = 3006;
    ///   * TRANSITION_ATTRIBUTES_CONFLICTING_DESTINATION_TAGS_FIELDS = 3007;
    ///   * TRANSITION_ATTRIBUTES_DELAY_DURATION_NEGATIVE_OR_NAN = 3008;
    ///   * TRANSITION_ATTRIBUTES_DELAY_DURATION_EXCEEDS_GLOBAL_DURATION = 3009;
    /// * AMOUNT_ERROR = 31;
    ///
    ///   * AMOUNT_NEGATIVE_VALUE = 3100;
    /// * LOAD_LIMIT_ERROR = 33;
    ///
    ///   * LOAD_LIMIT_INVALID_COST_ABOVE_SOFT_MAX = 3303;
    ///   * LOAD_LIMIT_SOFT_MAX_WITHOUT_COST_ABOVE_SOFT_MAX = 3304;
    ///   * LOAD_LIMIT_COST_ABOVE_SOFT_MAX_WITHOUT_SOFT_MAX = 3305;
    ///   * LOAD_LIMIT_NEGATIVE_SOFT_MAX = 3306;
    ///   * LOAD_LIMIT_MIXED_DEMAND_TYPE = 3307;
    ///   * LOAD_LIMIT_MAX_LOAD_NEGATIVE_VALUE = 3308;
    ///   * LOAD_LIMIT_SOFT_MAX_ABOVE_MAX = 3309;
    /// * INTERVAL_ERROR = 34;
    ///
    ///   * INTERVAL_MIN_EXCEEDS_MAX = 3401;
    ///   * INTERVAL_NEGATIVE_MIN = 3402;
    ///   * INTERVAL_NEGATIVE_MAX = 3403;
    ///   * INTERVAL_MIN_EXCEEDS_CAPACITY = 3404;
    ///   * INTERVAL_MAX_EXCEEDS_CAPACITY = 3405;
    /// * DISTANCE_LIMIT_ERROR = 36;
    ///
    ///   * DISTANCE_LIMIT_INVALID_COST_AFTER_SOFT_MAX = 3601;
    ///   * DISTANCE_LIMIT_SOFT_MAX_WITHOUT_COST_AFTER_SOFT_MAX = 3602;
    ///   * DISTANCE_LIMIT_COST_AFTER_SOFT_MAX_WITHOUT_SOFT_MAX = 3603;
    ///   * DISTANCE_LIMIT_NEGATIVE_MAX = 3604;
    ///   * DISTANCE_LIMIT_NEGATIVE_SOFT_MAX = 3605;
    ///   * DISTANCE_LIMIT_SOFT_MAX_LARGER_THAN_MAX = 3606;
    /// * DURATION_LIMIT_ERROR = 38;
    ///
    ///   * DURATION_LIMIT_MAX_DURATION_NEGATIVE_OR_NAN = 3800;
    ///   * DURATION_LIMIT_SOFT_MAX_DURATION_NEGATIVE_OR_NAN = 3801;
    ///   * DURATION_LIMIT_INVALID_COST_PER_HOUR_AFTER_SOFT_MAX = 3802;
    ///   * DURATION_LIMIT_SOFT_MAX_WITHOUT_COST_AFTER_SOFT_MAX = 3803;
    ///   * DURATION_LIMIT_COST_AFTER_SOFT_MAX_WITHOUT_SOFT_MAX = 3804;
    ///   * DURATION_LIMIT_QUADRATIC_SOFT_MAX_DURATION_NEGATIVE_OR_NAN = 3805;
    ///   * DURATION_LIMIT_INVALID_COST_AFTER_QUADRATIC_SOFT_MAX = 3806;
    ///   * DURATION_LIMIT_QUADRATIC_SOFT_MAX_WITHOUT_COST_PER_SQUARE_HOUR
    ///     = 3807;
    ///   * DURATION_LIMIT_COST_PER_SQUARE_HOUR_WITHOUT_QUADRATIC_SOFT_MAX
    ///     = 3808;
    ///   * DURATION_LIMIT_QUADRATIC_SOFT_MAX_WITHOUT_MAX = 3809;
    ///   * DURATION_LIMIT_SOFT_MAX_LARGER_THAN_MAX = 3810;
    ///   * DURATION_LIMIT_QUADRATIC_SOFT_MAX_LARGER_THAN_MAX = 3811;
    ///   * DURATION_LIMIT_DIFF_BETWEEN_MAX_AND_QUADRATIC_SOFT_MAX_TOO_LARGE
    ///     = 3812;
    ///   * DURATION_LIMIT_MAX_DURATION_EXCEEDS_GLOBAL_DURATION = 3813;
    ///   * DURATION_LIMIT_SOFT_MAX_DURATION_EXCEEDS_GLOBAL_DURATION = 3814;
    ///   * DURATION_LIMIT_QUADRATIC_SOFT_MAX_DURATION_EXCEEDS_GLOBAL_DURATION
    ///     = 3815;
    /// * SHIPMENT_ERROR = 40;
    ///
    ///   * SHIPMENT_PD_LIMIT_WITHOUT_PICKUP_AND_DELIVERY = 4014;
    ///   * SHIPMENT_PD_ABSOLUTE_DETOUR_LIMIT_DURATION_NEGATIVE_OR_NAN = 4000;
    ///   * SHIPMENT_PD_ABSOLUTE_DETOUR_LIMIT_DURATION_EXCEEDS_GLOBAL_DURATION
    ///     = 4001;
    ///   * SHIPMENT_PD_RELATIVE_DETOUR_LIMIT_INVALID = 4015;
    ///   * SHIPMENT_PD_DETOUR_LIMIT_AND_EXTRA_VISIT_DURATION = 4016;
    ///   * SHIPMENT_PD_TIME_LIMIT_DURATION_NEGATIVE_OR_NAN = 4002;
    ///   * SHIPMENT_PD_TIME_LIMIT_DURATION_EXCEEDS_GLOBAL_DURATION = 4003;
    ///   * SHIPMENT_EMPTY_SHIPMENT_TYPE = 4004;
    ///   * SHIPMENT_NO_PICKUP_NO_DELIVERY = 4005;
    ///   * SHIPMENT_INVALID_PENALTY_COST = 4006;
    ///   * SHIPMENT_ALLOWED_VEHICLE_INDEX_OUT_OF_BOUNDS = 4007;
    ///   * SHIPMENT_DUPLICATE_ALLOWED_VEHICLE_INDEX = 4008;
    ///   * SHIPMENT_INCONSISTENT_COST_FOR_VEHICLE_SIZE_WITHOUT_INDEX = 4009;
    ///   * SHIPMENT_INCONSISTENT_COST_FOR_VEHICLE_SIZE_WITH_INDEX = 4010;
    ///   * SHIPMENT_INVALID_COST_FOR_VEHICLE = 4011;
    ///   * SHIPMENT_COST_FOR_VEHICLE_INDEX_OUT_OF_BOUNDS = 4012;
    ///   * SHIPMENT_DUPLICATE_COST_FOR_VEHICLE_INDEX = 4013;
    /// * VEHICLE_ERROR = 42;
    ///
    ///   * VEHICLE_EMPTY_REQUIRED_OPERATOR_TYPE = 4200;
    ///   * VEHICLE_DUPLICATE_REQUIRED_OPERATOR_TYPE = 4201;
    ///   * VEHICLE_NO_OPERATOR_WITH_REQUIRED_OPERATOR_TYPE = 4202;
    ///   * VEHICLE_EMPTY_START_TAG = 4203;
    ///   * VEHICLE_DUPLICATE_START_TAG = 4204;
    ///   * VEHICLE_EMPTY_END_TAG = 4205;
    ///   * VEHICLE_DUPLICATE_END_TAG = 4206;
    ///   * VEHICLE_EXTRA_VISIT_DURATION_NEGATIVE_OR_NAN = 4207;
    ///   * VEHICLE_EXTRA_VISIT_DURATION_EXCEEDS_GLOBAL_DURATION = 4208;
    ///   * VEHICLE_EXTRA_VISIT_DURATION_EMPTY_KEY = 4209;
    ///   * VEHICLE_FIRST_SHIPMENT_INDEX_OUT_OF_BOUNDS = 4210;
    ///   * VEHICLE_FIRST_SHIPMENT_IGNORED = 4211;
    ///   * VEHICLE_FIRST_SHIPMENT_NOT_BOUND = 4212;
    ///   * VEHICLE_LAST_SHIPMENT_INDEX_OUT_OF_BOUNDS = 4213;
    ///   * VEHICLE_LAST_SHIPMENT_IGNORED = 4214;
    ///   * VEHICLE_LAST_SHIPMENT_NOT_BOUND = 4215;
    ///   * VEHICLE_IGNORED_WITH_USED_IF_ROUTE_IS_EMPTY = 4216;
    ///   * VEHICLE_INVALID_COST_PER_KILOMETER = 4217;
    ///   * VEHICLE_INVALID_COST_PER_HOUR = 4218;
    ///   * VEHICLE_INVALID_COST_PER_TRAVELED_HOUR = 4219;
    ///   * VEHICLE_INVALID_FIXED_COST = 4220;
    ///   * VEHICLE_INVALID_TRAVEL_DURATION_MULTIPLE = 4221;
    ///   * VEHICLE_TRAVEL_DURATION_MULTIPLE_WITH_SHIPMENT_PD_DETOUR_LIMITS
    ///     = 4223;
    ///   * VEHICLE_MATRIX_INDEX_WITH_SHIPMENT_PD_DETOUR_LIMITS = 4224;
    ///   * VEHICLE_MINIMUM_DURATION_LONGER_THAN_DURATION_LIMIT = 4222;
    /// * VISIT_REQUEST_ERROR = 44;
    ///
    ///   * VISIT_REQUEST_EMPTY_TAG = 4400;
    ///   * VISIT_REQUEST_DUPLICATE_TAG = 4401;
    ///   * VISIT_REQUEST_DURATION_NEGATIVE_OR_NAN = 4404;
    ///   * VISIT_REQUEST_DURATION_EXCEEDS_GLOBAL_DURATION = 4405;
    /// * PRECEDENCE_ERROR = 46;
    ///
    ///   * PRECEDENCE_RULE_MISSING_FIRST_INDEX = 4600;
    ///   * PRECEDENCE_RULE_MISSING_SECOND_INDEX = 4601;
    ///   * PRECEDENCE_RULE_FIRST_INDEX_OUT_OF_BOUNDS = 4602;
    ///   * PRECEDENCE_RULE_SECOND_INDEX_OUT_OF_BOUNDS = 4603;
    ///   * PRECEDENCE_RULE_DUPLICATE_INDEX = 4604;
    ///   * PRECEDENCE_RULE_INEXISTENT_FIRST_VISIT_REQUEST = 4605;
    ///   * PRECEDENCE_RULE_INEXISTENT_SECOND_VISIT_REQUEST = 4606;
    /// * BREAK_ERROR = 48;
    ///
    ///   * BREAK_RULE_EMPTY = 4800;
    ///   * BREAK_REQUEST_UNSPECIFIED_DURATION = 4801;
    ///   * BREAK_REQUEST_UNSPECIFIED_EARLIEST_START_TIME = 4802;
    ///   * BREAK_REQUEST_UNSPECIFIED_LATEST_START_TIME = 4803;
    ///   * BREAK_REQUEST_DURATION_NEGATIVE_OR_NAN = 4804; = 4804;
    ///   * BREAK_REQUEST_LATEST_START_TIME_BEFORE_EARLIEST_START_TIME = 4805;
    ///   * BREAK_REQUEST_EARLIEST_START_TIME_BEFORE_GLOBAL_START_TIME = 4806;
    ///   * BREAK_REQUEST_LATEST_END_TIME_AFTER_GLOBAL_END_TIME = 4807;
    ///   * BREAK_REQUEST_NON_SCHEDULABLE = 4808;
    ///   * BREAK_FREQUENCY_MAX_INTER_BREAK_DURATION_NEGATIVE_OR_NAN = 4809;
    ///   * BREAK_FREQUENCY_MIN_BREAK_DURATION_NEGATIVE_OR_NAN = 4810;
    ///   * BREAK_FREQUENCY_MIN_BREAK_DURATION_EXCEEDS_GLOBAL_DURATION = 4811;
    ///   * BREAK_FREQUENCY_MAX_INTER_BREAK_DURATION_EXCEEDS_GLOBAL_DURATION
    ///     = 4812;
    ///   * BREAK_REQUEST_DURATION_EXCEEDS_GLOBAL_DURATION = 4813;
    ///   * BREAK_FREQUENCY_MISSING_MAX_INTER_BREAK_DURATION = 4814;
    ///   * BREAK_FREQUENCY_MISSING_MIN_BREAK_DURATION = 4815;
    /// * SHIPMENT_TYPE_INCOMPATIBILITY_ERROR = 50;
    ///
    ///   * SHIPMENT_TYPE_INCOMPATIBILITY_EMPTY_TYPE = 5001;
    ///   * SHIPMENT_TYPE_INCOMPATIBILITY_LESS_THAN_TWO_TYPES = 5002;
    ///   * SHIPMENT_TYPE_INCOMPATIBILITY_DUPLICATE_TYPE = 5003;
    ///   * SHIPMENT_TYPE_INCOMPATIBILITY_INVALID_INCOMPATIBILITY_MODE = 5004;
    ///   * SHIPMENT_TYPE_INCOMPATIBILITY_TOO_MANY_INCOMPATIBILITIES = 5005;
    /// * SHIPMENT_TYPE_REQUIREMENT_ERROR = 52;
    ///
    ///   * SHIPMENT_TYPE_REQUIREMENT_NO_REQUIRED_TYPE = 52001;
    ///   * SHIPMENT_TYPE_REQUIREMENT_NO_DEPENDENT_TYPE = 52002;
    ///   * SHIPMENT_TYPE_REQUIREMENT_INVALID_REQUIREMENT_MODE = 52003;
    ///   * SHIPMENT_TYPE_REQUIREMENT_TOO_MANY_REQUIREMENTS = 52004;
    ///   * SHIPMENT_TYPE_REQUIREMENT_EMPTY_REQUIRED_TYPE = 52005;
    ///   * SHIPMENT_TYPE_REQUIREMENT_DUPLICATE_REQUIRED_TYPE = 52006;
    ///   * SHIPMENT_TYPE_REQUIREMENT_NO_REQUIRED_TYPE_FOUND = 52007;
    ///   * SHIPMENT_TYPE_REQUIREMENT_EMPTY_DEPENDENT_TYPE = 52008;
    ///   * SHIPMENT_TYPE_REQUIREMENT_DUPLICATE_DEPENDENT_TYPE = 52009;
    ///   * SHIPMENT_TYPE_REQUIREMENT_SELF_DEPENDENT_TYPE = 52010;
    ///   * SHIPMENT_TYPE_REQUIREMENT_GRAPH_HAS_CYCLES = 52011;
    /// * VEHICLE_OPERATOR_ERROR = 54;
    ///
    ///   * VEHICLE_OPERATOR_EMPTY_TYPE = 5400;
    ///   * VEHICLE_OPERATOR_MULTIPLE_START_TIME_WINDOWS = 5401;
    ///   * VEHICLE_OPERATOR_SOFT_START_TIME_WINDOW = 5402;
    ///   * VEHICLE_OPERATOR_MULTIPLE_END_TIME_WINDOWS = 5403;
    ///   * VEHICLE_OPERATOR_SOFT_END_TIME_WINDOW = 5404;
    /// * DURATION_SECONDS_MATRIX_ERROR = 56;
    ///
    ///   * DURATION_SECONDS_MATRIX_DURATION_NEGATIVE_OR_NAN = 5600;
    ///   * DURATION_SECONDS_MATRIX_DURATION_EXCEEDS_GLOBAL_DURATION = 5601;
    pub code: i32,

    /// The error display name.
    pub display_name: std::string::String,

    /// An error context may involve 0, 1 (most of the time) or more fields. For
    /// example, referring to vehicle #4 and shipment #2's first pickup can be
    /// done as follows:
    ///
    /// ```norust
    /// fields { name: "vehicles" index: 4}
    /// fields { name: "shipments" index: 2 sub_field {name: "pickups" index: 0} }
    /// ```
    ///
    /// Note, however, that the cardinality of `fields` should not change for a
    /// given error code.
    pub fields: std::vec::Vec<crate::model::optimize_tours_validation_error::FieldReference>,

    /// Human-readable string describing the error. There is a 1:1 mapping
    /// between `code` and `error_message` (when code != "UNSPECIFIED").
    ///
    /// *STABILITY*: Not stable: the error message associated to a given `code` may
    /// change (hopefully to clarify it) over time. Please rely on the
    /// `display_name` and `code` instead.
    pub error_message: std::string::String,

    /// May contain the value(s) of the field(s). This is not always available. You
    /// should absolutely not rely on it and use it only for manual model
    /// debugging.
    pub offending_values: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl OptimizeToursValidationError {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [code][crate::model::OptimizeToursValidationError::code].
    pub fn set_code<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.code = v.into();
        self
    }

    /// Sets the value of [display_name][crate::model::OptimizeToursValidationError::display_name].
    pub fn set_display_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.display_name = v.into();
        self
    }

    /// Sets the value of [fields][crate::model::OptimizeToursValidationError::fields].
    pub fn set_fields<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::optimize_tours_validation_error::FieldReference>,
    {
        use std::iter::Iterator;
        self.fields = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [error_message][crate::model::OptimizeToursValidationError::error_message].
    pub fn set_error_message<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.error_message = v.into();
        self
    }

    /// Sets the value of [offending_values][crate::model::OptimizeToursValidationError::offending_values].
    pub fn set_offending_values<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.offending_values = v.into();
        self
    }
}

impl wkt::message::Message for OptimizeToursValidationError {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.optimization.v1.OptimizeToursValidationError"
    }
}

/// Defines additional types related to [OptimizeToursValidationError].
pub mod optimize_tours_validation_error {
    #[allow(unused_imports)]
    use super::*;

    /// Specifies a context for the validation error. A `FieldReference` always
    /// refers to a given field in this file and follows the same hierarchical
    /// structure. For example, we may specify element #2 of `start_time_windows`
    /// of vehicle #5 using:
    ///
    /// ```norust
    /// name: "vehicles" index: 5 sub_field { name: "end_time_windows" index: 2 }
    /// ```
    ///
    /// We however omit top-level entities such as `OptimizeToursRequest` or
    /// `ShipmentModel` to avoid crowding the message.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct FieldReference {
        /// Name of the field, e.g., "vehicles".
        pub name: std::string::String,

        /// Recursively nested sub-field, if needed.
        pub sub_field: std::option::Option<
            std::boxed::Box<crate::model::optimize_tours_validation_error::FieldReference>,
        >,

        pub index_or_key: std::option::Option<
            crate::model::optimize_tours_validation_error::field_reference::IndexOrKey,
        >,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl FieldReference {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [name][crate::model::optimize_tours_validation_error::FieldReference::name].
        pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.name = v.into();
            self
        }

        /// Sets the value of [sub_field][crate::model::optimize_tours_validation_error::FieldReference::sub_field].
        pub fn set_sub_field<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::optimize_tours_validation_error::FieldReference>,
        {
            self.sub_field = std::option::Option::Some(std::boxed::Box::new(v.into()));
            self
        }

        /// Sets or clears the value of [sub_field][crate::model::optimize_tours_validation_error::FieldReference::sub_field].
        pub fn set_or_clear_sub_field<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::optimize_tours_validation_error::FieldReference>,
        {
            self.sub_field = v.map(|x| std::boxed::Box::new(x.into()));
            self
        }

        /// Sets the value of [index_or_key][crate::model::optimize_tours_validation_error::FieldReference::index_or_key].
        ///
        /// Note that all the setters affecting `index_or_key` are mutually
        /// exclusive.
        pub fn set_index_or_key<
            T: std::convert::Into<
                    std::option::Option<
                        crate::model::optimize_tours_validation_error::field_reference::IndexOrKey,
                    >,
                >,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.index_or_key = v.into();
            self
        }

        /// The value of [index_or_key][crate::model::optimize_tours_validation_error::FieldReference::index_or_key]
        /// if it holds a `Index`, `None` if the field is not set or
        /// holds a different branch.
        pub fn index(&self) -> std::option::Option<&i32> {
            #[allow(unreachable_patterns)]
            self.index_or_key.as_ref().and_then(|v| match v {
                crate::model::optimize_tours_validation_error::field_reference::IndexOrKey::Index(v) => std::option::Option::Some(v),
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [index_or_key][crate::model::optimize_tours_validation_error::FieldReference::index_or_key]
        /// to hold a `Index`.
        ///
        /// Note that all the setters affecting `index_or_key` are
        /// mutually exclusive.
        pub fn set_index<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
            self.index_or_key = std::option::Option::Some(
                crate::model::optimize_tours_validation_error::field_reference::IndexOrKey::Index(
                    v.into(),
                ),
            );
            self
        }

        /// The value of [index_or_key][crate::model::optimize_tours_validation_error::FieldReference::index_or_key]
        /// if it holds a `Key`, `None` if the field is not set or
        /// holds a different branch.
        pub fn key(&self) -> std::option::Option<&std::string::String> {
            #[allow(unreachable_patterns)]
            self.index_or_key.as_ref().and_then(|v| match v {
                crate::model::optimize_tours_validation_error::field_reference::IndexOrKey::Key(
                    v,
                ) => std::option::Option::Some(v),
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [index_or_key][crate::model::optimize_tours_validation_error::FieldReference::index_or_key]
        /// to hold a `Key`.
        ///
        /// Note that all the setters affecting `index_or_key` are
        /// mutually exclusive.
        pub fn set_key<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.index_or_key = std::option::Option::Some(
                crate::model::optimize_tours_validation_error::field_reference::IndexOrKey::Key(
                    v.into(),
                ),
            );
            self
        }
    }

    impl wkt::message::Message for FieldReference {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.optimization.v1.OptimizeToursValidationError.FieldReference"
        }
    }

    /// Defines additional types related to [FieldReference].
    pub mod field_reference {
        #[allow(unused_imports)]
        use super::*;

        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum IndexOrKey {
            /// Index of the field if repeated.
            Index(i32),
            /// Key if the field is a map.
            Key(std::string::String),
        }
    }
}

/// Data formats for input and output files.
///
/// # Working with unknown values
///
/// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
/// additional enum variants at any time. Adding new variants is not considered
/// a breaking change. Applications should write their code in anticipation of:
///
/// - New values appearing in future releases of the client library, **and**
/// - New values received dynamically, without application changes.
///
/// Please consult the [Working with enums] section in the user guide for some
/// guidelines.
///
/// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum DataFormat {
    /// Default value.
    Unspecified,
    /// Input data in json format.
    Json,
    /// Input data in string format.
    String,
    /// If set, the enum was initialized with an unknown value.
    ///
    /// Applications can examine the value using [DataFormat::value] or
    /// [DataFormat::name].
    UnknownValue(data_format::UnknownValue),
}

#[doc(hidden)]
pub mod data_format {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Clone, Debug, PartialEq)]
    pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
}

impl DataFormat {
    /// Gets the enum value.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the string representation of enums.
    pub fn value(&self) -> std::option::Option<i32> {
        match self {
            Self::Unspecified => std::option::Option::Some(0),
            Self::Json => std::option::Option::Some(1),
            Self::String => std::option::Option::Some(2),
            Self::UnknownValue(u) => u.0.value(),
        }
    }

    /// Gets the enum value as a string.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the integer representation of enums.
    pub fn name(&self) -> std::option::Option<&str> {
        match self {
            Self::Unspecified => std::option::Option::Some("DATA_FORMAT_UNSPECIFIED"),
            Self::Json => std::option::Option::Some("JSON"),
            Self::String => std::option::Option::Some("STRING"),
            Self::UnknownValue(u) => u.0.name(),
        }
    }
}

impl std::default::Default for DataFormat {
    fn default() -> Self {
        use std::convert::From;
        Self::from(0)
    }
}

impl std::fmt::Display for DataFormat {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        wkt::internal::display_enum(f, self.name(), self.value())
    }
}

impl std::convert::From<i32> for DataFormat {
    fn from(value: i32) -> Self {
        match value {
            0 => Self::Unspecified,
            1 => Self::Json,
            2 => Self::String,
            _ => Self::UnknownValue(data_format::UnknownValue(
                wkt::internal::UnknownEnumValue::Integer(value),
            )),
        }
    }
}

impl std::convert::From<&str> for DataFormat {
    fn from(value: &str) -> Self {
        use std::string::ToString;
        match value {
            "DATA_FORMAT_UNSPECIFIED" => Self::Unspecified,
            "JSON" => Self::Json,
            "STRING" => Self::String,
            _ => Self::UnknownValue(data_format::UnknownValue(
                wkt::internal::UnknownEnumValue::String(value.to_string()),
            )),
        }
    }
}

impl serde::ser::Serialize for DataFormat {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Unspecified => serializer.serialize_i32(0),
            Self::Json => serializer.serialize_i32(1),
            Self::String => serializer.serialize_i32(2),
            Self::UnknownValue(u) => u.0.serialize(serializer),
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for DataFormat {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_any(wkt::internal::EnumVisitor::<DataFormat>::new(
            ".google.cloud.optimization.v1.DataFormat",
        ))
    }
}
